我是靠谱客的博主 受伤高跟鞋,最近开发中收集的这篇文章主要介绍LiveData简单使用,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

         androidx包内的MutableLiveData,如果先发送value,再被观察者订阅,新的观察者能收到订阅前发送的value,这就是liveData 的粘性。 
  阅读LiveData 源码, 相关方法依次为
onStateChanged=》activeStateChanged=》dispatchingValue=》considerNotify,
 最后有一个是否接收value 的判断,
if (observer.mLastVersion >= mVersion) {
    return;
}

只有observer 中的mLastVersion<mVersion时,观察者才能接收到数据。

由此,如果要求观察者只能收到订阅之后发送的value,我们只需要在订阅时,将mLastVersion的值设置为mVersion,就可以解决问题。

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

    private boolean stickyFlag = false;

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

    //在这里去改变onChange 的流程
    private void hook(Observer<? super T> observer){
        try{
            // 得到 mLastVersion
            //获取到liveData 的类中的mObserver 对象
            //SafeIterableMap<Observer<? super T>,ObserverWrapper>  mObservers
            Class<LiveData> liveDataClass = LiveData.class;
            Field mObserversField = liveDataClass.getDeclaredField("mObservers");
            mObserversField.setAccessible(true);
            Object mObserversObject = mObserversField.get(this);
            //得到map 对应的class 对象
            Class<?> mObserversClass = mObserversObject.getClass();
            //  获取到mObserver 对象的get 方法   entry
            Method get = mObserversClass.getMethod("get", mObserversClass);
            get.setAccessible(true);
            //执行get 方法   mObservers.get(observer)
            Object invokeEntry = get.invoke(mObserversObject, observer);
            //定义一个空的对象
            Object observerWrapper = null;
            if(invokeEntry != null && invokeEntry instanceof Map.Entry){
                observerWrapper = ((Map.Entry) invokeEntry).getValue();
            }
            if(observerWrapper == null){
                throw new NullPointerException("observerWrapper  is  null");
            }
            //得到ObserverWrapper的类对象,编译擦除问题会引起多态冲突所以用getSupperClass
            Class<?> superclass = observerWrapper.getClass().getSuperclass(); //ObserverWrapper
            Field mLastVersion = superclass.getDeclaredField("mLastVersion");
            mLastVersion.setAccessible(true);
            //得到mVersion
            Field mVersion = liveDataClass.getDeclaredField("mVersion");
            mVersion.setAccessible(true);
            //把mVersion 的值写入到mLastVersion 中
            Object mVersionValue = mVersion.get(this);
            mLastVersion.set(mLastVersion, mVersionValue);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
public class LiveDataBus{
    //存放订阅者

    private Map<String, MutableLiveData<Object>> bus;

    private static LiveDataBus liveDataBus = new LiveDataBus();

    private LiveDataBus(){
        bus = new HashMap<>();
    }

    public static LiveDataBus getInstance(){
        return liveDataBus;
    }

    //LiveData存入map
    public synchronized <T> MutableLiveData<T> with(String key, Class<T> type){
        if(!bus.containsKey(key)){
            bus.put(key, new MutableLiveData<>());
        }
        return (MutableLiveData<T>) bus.get(key);
    }

    //LiveData存入map     非粘性
    public synchronized <T> NonStickyMutableLiveData<T> withNonStick(String key, Class<T> type){
        if(!bus.containsKey(key)){
            bus.put(key, new NonStickyMutableLiveData<>());
        }
        return (NonStickyMutableLiveData<T>) bus.get(key);
    }

    public synchronized void remove(String key){
        bus.remove(key);
    }


    public synchronized void removeAll(){
        bus.clear();
    }
}

最后

以上就是受伤高跟鞋为你收集整理的LiveData简单使用的全部内容,希望文章能够帮你解决LiveData简单使用所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部