安卓系列之Jetpack架构(AAC):LiveData基础篇

163 阅读2分钟

有生命的数据,依据Activity,Fragment或者service的生命周期的活跃情况更新数据。一般在ViewModel中创建liveData,在Activity或者Fragment中创建Observer对象更新UI。

优点

  1. 避免内存泄漏
  2. 数据在Activity或者Fragment活跃时更新

注意点

  1. 非UI线程需要使用postValue()方法
  2. observeForever()表示一直处于观察模式
  3. 尽量在ViewModel中使用liveData存储数据,这样Activity和Fragment仅负责显示数据

随Activity或者Fragment的生命周期更新数据

实例代码

package com.elaine.testlivedata;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;

public class MainActivity extends AppCompatActivity {
    private MutableLiveData<String> userName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("activity===""onCreate");
        testLiveData();
    }

    private void testLiveData() {
        userName = new MutableLiveData<>();
        userName.observe(thisnew Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.e("change----", s);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.e("activity===""onStart");
        userName.setValue("onStart:username==eeee");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.e("activity===""onResume");
        userName.setValue("onResume:username==aaaa");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.e("activity===""onRestart");
        userName.setValue("onRestart:username==ffff");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e("activity===""onPause");
        userName.setValue("onPause:username==bbbb");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.e("activity===""onStop");
        userName.setValue("onStop:username==cccc");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("activity===""onDestroy");
        userName.setValue("onDestroy:username==dddd");
    }
}

操作过程

打开APP,然后按home键,然后再点击APP,然后双击返回关闭APP

日志打印结果

图片

结果分析

在onStart(),onResume()和onPause()这三个方法中执行setValue(),那么可以更新数据,即这三个状态对于liveData来说是活跃状态,需要更新数据。

拓展LiveData

实现LiveData单例,即可实现多个Activity、Fragment和Service之间共享数据。
官方例子

public class StockLiveData extends LiveData<BigDecimal> {
    private static StockLiveData sInstance;
    private StockManager stockManager;

    private SimplePriceListener listener = new SimplePriceListener() {
        @Override
        public void onPriceChanged(BigDecimal price) {
            setValue(price);
        }
    };

    @MainThread
    public static StockLiveData get(String symbol) {
        if (sInstance == null) {
            sInstance = new StockLiveData(symbol);
        }
        return sInstance;
    }

    private StockLiveData(String symbol) {
        stockManager = new StockManager(symbol);
    }

    @Override
    protected void onActive() {
        stockManager.requestPriceUpdates(listener);
    }

    @Override
    protected void onInactive() {
        stockManager.removeUpdates(listener);
    }
}

转换LiveData

Transformations.map()

实例代码

/**
 * 把用户的UserId转为字符串,前面加上"用户ID:",用于UI填充
 */
private void use() {
    MutableLiveData<Integer> userId = new MutableLiveData<>();
    LiveData<String> userIdString = Transformations.map(userId, new Function<IntegerString>() {
        @Override
        public String apply(Integer userId) {
            return "用户ID:" + userId;
        }
    });
    userIdString.observe(thisnew Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.e("更改后的数据====", s);
            }
    });
    userId.setValue(13);
}

运行结果
图片

Transformations.switchMap()

实例代码


    /**
     * 功能:判断男孩还是女孩
     */
    private void useTwo() {
        MutableLiveData<Integer> sex = new MutableLiveData<>();
        MutableLiveData<String> girl = new MutableLiveData<>();
        MutableLiveData<String> boy = new MutableLiveData<>();
        LiveData<String> sexString = Transformations.switchMap(sex, new Function<IntegerLiveData<String>>() {

            @Override
            public LiveData<Stringapply(Integer input) {
                if (input == 0) {
                    return girl;
                }
                return boy;
            }
        });
        sexString.observe(thisnew Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.e("sex===", s);
            }
        });
        girl.setValue("女孩");
        boy.setValue("男孩");
        sex.setValue(0);
    }

运行结果
图片

合并LiveData

一个观察者观察多个对象的变化,一对多关系。
实例代码

    /**
     * 功能:先读本地的内容,再读网络的内容,如果网络有,则优先网络的内容,若无,则默认本地的内容
     */
    private void useThree() {
        //本地储存得到的跳转到QQ的地址字符串
        MutableLiveData<String> toQQLocal = new MutableLiveData<>();
        //网络请求得到的跳转到QQ的地址字符串
        MutableLiveData<String> toQQNetwork = new MutableLiveData<>();
        //合并观察者
        MediatorLiveData<String> toQQMediator = new MediatorLiveData<>();

        toQQMediator.addSource(toQQLocal, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                toQQMediator.setValue(s);
            }
        });
        toQQMediator.addSource(toQQNetwork, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                toQQMediator.setValue(s);
            }
        });
        toQQMediator.observe(thisnew Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.e("qq====", s);
            }
        });

        toQQLocal.setValue("local===To====QQ");
        toQQNetwork.setValue("network===To===QQ");
    }

运行结果
图片

项目github地址

github.com/ElaineTaylo…

若帅哥美女对该系列文章感兴趣,可微信搜索公众号(木子闲集)关注更多更新文章哦,谢谢~