关于 LiveData 粘性事件的个人思考

1. 问题描述

  1.1. LiveData特性:
    Google官方文档中描述,设备横竖屏切换的时候,界面销毁重建,但是Activity生命周期并未结束,旋转后新建的空页面上数据需要重新填充,所以LiveData在被再次观察时会立即推送数据更新。
      Google文档

      ViewModel生命周期

  未使用LiveData效果演示

 

使用LiveData效果演示

1.2. 源码分析:
    LiveData关于此特性的源码分析,有兴趣的可以看看下面的文章:
    Android消息总线的演进之路:用LiveDataBus替代RxBus、EventBus
    UnPeekLiveData

  1.3. 如果多个界面共用一个ViewModel(其生命周期大于绑定的所有界面),并且复用了同一个LiveData数据源,LiveData数据源在前一个界面被更新过,那么下一个界面在刚刚绑定观察该LiveData时,就会被通知数据发生变化,LiveData最新值会立即推送过来,在一部分场景下可能显得多此一举,或者引发错误。

2. 个人思考总结

  2.1. 如果没有多个界面共用同一个ViewModel的需求,或者经常需要用到粘性特性,则无需特殊处理。

  2.2. 如果不想使用LiveData的粘性特性,需要自己写一个LiveData继承类来代替MutableLiveData,通过反射或者逻辑判断来规避掉粘性特性(细节可以看上面的源码分析文章)。我自己也写了个很简洁的LiveData实现类,通过判断数据源有无被更改过,控制是否将订阅后的第一次推送通知到界面。代码如下:

public class CleanLiveData<T> extends LiveData<T> {
    private boolean hasModified = false;
 
    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull final Observer<? super T> observer) {
        super.observe(owner, new Observer<T>() {
            private boolean hasIntercept = false;
 
            @Override
            public void onChanged(T t) {
                if (!hasModified || hasIntercept) {
                    observer.onChanged(t);
                }
                hasIntercept = true;
            }
        });
    }
 
    @Override
    public void observeForever(@NonNull final Observer<? super T> observer) {
        super.observeForever(new Observer<T>() {
            private boolean hasIntercept = false;
 
            @Override
            public void onChanged(T t) {
                if (!hasModified || hasIntercept) {
                    observer.onChanged(t);
                }
                hasIntercept = true;
            }
        });
    }
 
    @Override
    public void setValue(T value) {
        super.setValue(value);
        hasModified = true;
    }
 
    @Override
    public void postValue(T value) {
        super.postValue(value);
        hasModified = true;
    }
}

   2.3. Demo项目地址:
LiveDataTest



作者:蜂鸟之歌
链接:https://www.jianshu.com/p/f25b0e32b5bb
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值