美文网首页
MutableLiveData和LiveData

MutableLiveData和LiveData

作者: 田田ww | 来源:发表于2020-11-09 14:42 被阅读0次

    LiveData是Google Jetpack库中提供的一种可观察的数据存储器类,是一种可以与任意数据类型一起使用的包装器。
    LiveData可以感知生命周期,观察者(Observer)处于StartedResumed状态时,LiveData认为该观察者处于活跃状态,会将更新通知给活跃观察者,而已注册非活跃状态的观察者不会收到更新。这样当Activity和Fragment生命周期结束时,便可移除观察者而不必担心泄露。

    LiveData特点:

    1. 在LiveData的观察者对象中进行与数据状态相关的界面更新操作;
    2. 观察者会绑定Lifecycle对象,当与其关联的生命周期结束时进行自我清理;
    3. 当activity或fragment由非活跃状态变为活跃状态时,会立即接收最新数据;
    4. 设备配置更改时(例如屏幕旋转或中英文切换)而创建新activity或fragment时会接收最新数据;
    5. 可使用单例模式扩展LiveData对象并包装成系统服务,以便在应用程序中共享(事件总线LiveDataBus)。

    MutableLiveData和LiveData

    1. MutableLiveData继承自LiveData;
    2. LiveData可以通知指定的某字段的数据更新,外部需MutableLiveData类才能改变容器内容;
    3. MutableLiveData整个实体类或数据类型变化后才通知,不会细节到字段;
    4. MutableLiveData提供了改变容器内容的接口setValue/postValue

    LiveData使用

    1、创建LiveData对象
    MVVM模式下,一般在ViewModel中声明和保存LiveData,主要目的是:

    • Activity和Fragment中只进行UI数据显示,数据状态变更在ViewModel中进行
    • LiveData在ViewModel中声明时,生命周期与activity或fragment分离,配置变更后LiveData仍然存活。

    2、订阅LiveData对象
    官方推荐在onCreate()方法中开始观察LiveData对象理由是:

    • 确保在Activity或Fragment一变为活跃状态就可以接收更新数据
    • 确保系统不会在activity或Fragment的onResume()方法中进行多余调用

    第一种使用LiveData方法

    //ViewModel类创建LiveData示例
    public class XViewModel extends ViewModel{
        MutableLiveData<String> msgData;
        public MutableLiveData<String> getMsgData(){
            if (msgData == null){
                msgData = new MutableLiveData<>();
            }
            return msgData;
        }
        public void request(MutableLiveData<String> msgData, Param param){
            //请求网络数据,将msgData作为参数传递, 在请求的回调中使用postValue给msgData赋值
        }
    }
    
    //activity中订阅观察者
    viewModel.getMsgData().observe(this, new Observer<String>(){
        @override
        public void onChanged(String s){
        //UI数据操作        
    } );
    

    第二种使用LiveData方法(Transformations.switchMap)
    Transformations.switchMap介绍

    • 谷歌为LiveData组件提供的对存储在LiveData中的值进行更改后再分配给观察者的方法;
    • LiveData包提供Transformations类支持对LiveData对象内部值的修改;
    • Transformations.map()强调的是改变当前LiveData内部数据,返回的结果与传入的LiveData直接相关,例如字符串修改,数据值更改等;
    • Transformations.switchMap根据当前LiveData,返回一个LiveData类型的数据,可用来获取网络数据
    public class XViewModel extends ViewModel{
        //创建对请求参数进行观测的LiveData对象
        private MutableLiveData<String> reqData = new MutableLiveData<>();
        //创建对请求结果进行观测的LiveData对象
        public LiveData<String> msgData = Transformations.switchMap(reqData, this::requestMsgData);
       
        public LiveData<String> requestMsgData(RequestData reqData) 
       {
               //请求网络数据,方法返回值为LiveData<String>类型
        }
       }
    
    //LiveData直接在activity或fragment中设置观察
    //在dealData中处理UI数据
    viewModel.msgData.observer(this, this::dealData);
    

    postValue()
    postValue的特性如下:

    • 此方法可以在其他线程中调用
    • 如果在主线程执行发布的任务之前多次调用此方法,则仅将分配最后一个值。
    • 如果同时调用 postValue(“a”)和setValue(“b”),一定是值b被值a覆盖。

    setValue()
    setValue()的特性如下:

    • 此方法只能在主线程里调用

    最近遇到一个情况,对同一个LiveData连续多次setvalue时也存在仅分配最后一个值的问题,对调用做了延时但是治标不治本,后续再解决。
    解决办法:上述情况出现在用于对主线程传递事件的情况,连续多次调用同一个接口,用LiveData传递接口返回事件到主线程就会存在较短时间内对同一个LiveData对象赋值而LiveData只抛最后一次事件到主线程的情况,解决方法见如下链接
    把 LiveData 用于事件传递那些坑

    相关文章

      网友评论

          本文标题:MutableLiveData和LiveData

          本文链接:https://www.haomeiwen.com/subject/wrmcsktx.html