Android Jetpack 之 LiveData

Android Jetpack 之 LiveData

1 简介

官方定义

LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity/Fragment)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

拆解开来:

  • LiveData是一个数据持有者,给源数据包装一层。
  • 源数据使用LiveData包装后,可以被observer观察,数据有更新时observer可感知。
  • 但 observer的感知,只发生在(Activity/Fragment)活跃生命周期状态(STARTED、RESUMED)。

2 接入

implementation 'androidx.lifecycle:lifecycle-livedata:2.2.0'

3 基本使用

以下说明使用 ViewModel+LiveData 方式

步骤一:创建LiveData实例,指定源数据类型

注意:MutableLiveData其实是继承自LiveData只不过就是暴露了下setValue跟postValue方法

public class MyViewModel extends ViewModel {

    public MutableLiveData stringLiveData;

    public MyViewModel() {
        stringiveData = new MutableLiveData<>();
    }

}

步骤二:创建Observer实例,实现onChanged()方法,用于接收源数据变化并刷新UI.

步骤三:LiveData实例使用observe()方法添加观察者,并传入LifecycleOwner。

步骤四:LiveData实例使用setValue()/postValue()更新源数据 (子线程要postValue())

注意:子线程改变值用postValue,因为在多线程中操作数据是不安全的,而postValue是通过synchronized关键字确保线程安全

  MyViewModel  viewModel = new ViewModelProvider(this).get(MyViewModel.class);
        //步骤三
        viewModel.stringLiveData.observe(this, new Observer() {
        //步骤二
            @Override
            public void onChanged(String s) {
                Log.e("MainActivity",s+"----");
            }
        });
        
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //步骤四
                viewModel.stringLiveData.setValue("哈哈哈哈");    
            }
        });

4 高级用法

4.1 数据修改 - Transformations.map

  • 在项目中我们经常回运到数据转换的问题比如int转换成string或者int转换成另一个对象
public class LiveDataViewModel extends ViewModel {
    private MutableLiveData userMutableLiveData;
    public LiveData age;
    
    public LiveDataViewModel() {
        userMutableLiveData = new MutableLiveData<>();
        age = Transformations.map(userMutableLiveData, new Function() {
            @Override
            public Integer apply(User input) {
                return input.getAge();
            }
        });
     public void addUser(User user){
        //这里值得注意的是setValue主线程用没问题,如果是子线程那就要用postValue
        // userMutableLiveData.postValue(user);
        if(Looper.myLooper() == Looper.getMainLooper()){
            userMutableLiveData.setValue(user);
        }else {
            userMutableLiveData.postValue(user);
        }
    }
}
  • 这时直接去监听age就行了,只要userMutableLiveData的值有改变我们就能立马监听到User类中的年龄了
   model.age.observe(this, new Observer() {
            @Override
            public void onChanged(Integer integer) {
                Log.e("MainActivity",integer+"--");
            }
        });

4.2 数据切换 - Transformations.switchMap

  • liveData3、liveData4是两个数据源,有一个判断条件来决定 取哪一个数据 ,这个条件就是liveDataSwitch,如果值为true则取liveData3,false则取liveData4。
	//两个liveData,由liveDataSwitch决定 返回哪个livaData数据
        MutableLiveData liveData3 = new MutableLiveData<>();
        MutableLiveData liveData4 = new MutableLiveData<>();
        
	//切换条件LiveData,liveDataSwitch的value 是切换条件
        MutableLiveData liveDataSwitch = new MutableLiveData<>();
        
	//liveDataSwitchMap由switchMap()方法生成,用于添加观察者
        LiveData liveDataSwitchMap = Transformations.switchMap(liveDataSwitch, new Function>() {
            @Override
            public LiveData apply(Boolean input) {
            //这里是具体切换逻辑:根据liveDataSwitch的value返回哪个liveData
                if (input) {
                    return liveData3;
                }
                return liveData4;
            }
        });


        //使用
        liveDataSwitchMap.observe(this, new Observer() {
            @Override
            public void onChanged(String s) {
                Log.i(TAG, "onChanged2: " + s);
            }
        });

        boolean switchValue = true;
        liveDataSwitch.setValue(switchValue);//设置切换条件值

        liveData3.setValue("liveData3");
        liveData4.setValue("liveData4");

4.3 观察多个数据 - MediatorLiveData

  • MediatorLiveData 是 LiveData 的子类,允许合并多个 LiveData 源。只要任何原始的 LiveData 源对象发生更改,就会触发 MediatorLiveData 对象的观察者。

在需要联动的地方使用,例如监听输入文本的长度。

  public MutableLiveData message = new MutableLiveData<>();
  public MediatorLiveData messageNumber = new MediatorLiveData<>();
  messageNumber.setValue(0);
  messageNumber.addSource(message, new Observer() {
            @Override
            public void onChanged(String s) {
                messageNumber.setValue(s.length());
        }
 });

你可能感兴趣的:(jetpack,android,mvvm)