LiveData去除粘性

通过上篇:LiveData的源码分析 我们知道LiveData的最后一次数据会产生粘性

根本原因就是ObserverWrapper.mLastVersion >= mVersion 没有拦住

所以只要我们想办法在观察者注册的时候(执行observe方法)修改mLastVersion的值让他等于LiveData中维护的mVersion这样这个判断就能拦住,数据也就没有粘性了

如何修改ObserverWrapper实现类LifecycleBoundObserver中的mLastVersion呢?

显然得用反射:

我们先获取LiveData中存储LifecycleBoundObserver的Map--->mObservers的实例,然后再通过get(key)方法获取LifecycleBoundObserver的实例,获取LiveData中mVersion的值,最后修改LifecycleBoundObserver的实例的mLastVersion的值让他等于mVersion就大功告成了

代码:

这是我直接改造的LiveData的代码:

public class MyLiveData<T> extends MutableLiveData<T>{

    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        super.observe(owner, observer);
        hook(observer);
    }

    private void hook(Observer<? super T> observer) {
        try {
            //解决粘性的关键就是mLastVersion = mVersion
            Class<?> liveDataClass = LiveData.class;
            //先找到保存LifecycleBoundObserver的map
            Field mObserversField = liveDataClass.getDeclaredField("mObservers");
            mObserversField.setAccessible(true);
            //Field.get(Field所在的类的实例)方法获取map的实例 反射基础
            Object mObserversObj = mObserversField.get(MyLiveData.this);

            Class<?> mObserversClass = mObserversObj.getClass();
            //获取get方法信息
            Method mapMethodGet = mObserversClass.getDeclaredMethod("get",Object.class);
            mapMethodGet.setAccessible(true);
            //mObservers就是以 observer为key以  Map.Entry<Observer<? super T>, ObserverWrapper>为value的
            //通过mObserver.get(observer)获取Map.Entry<Observer<? super T>, ObserverWrapper>的实例
            Object obj = mapMethodGet.invoke(mObserversObj,observer);
            //获取Entry的class
            Class<?> observerWrapperClass = obj.getClass();
            //获取Entry的getValue方法的信息
            Method getValue = observerWrapperClass.getDeclaredMethod("getValue");
            getValue.setAccessible(true);

            //执行Entry实例的getValue方法获取LifecycleBoundObserver实例
            Object wrapper = getValue.invoke(obj);
            Class<?> lifecycleBoundObserverClass = wrapper.getClass();
            //因为mLastVersion在父类中,子类的class不包含父类的信息 泛型基础,所以需要得到父类的class信息
            Class<?> wrapperClass = lifecycleBoundObserverClass.getSuperclass();
            Field mLastVersionField = wrapperClass.getDeclaredField("mLastVersion");
            mLastVersionField.setAccessible(true);
            //下面是取LiveData中维护的mVersion的值
            Field mVersionField = liveDataClass.getDeclaredField("mVersion");
            mVersionField.setAccessible(true);
            int mVersion  = mVersionField.getInt(MyLiveData.this);
            //修改mLastVersion中的值
            mLastVersionField.set(wrapper,mVersion);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值