LiveData使用以及源码详解

62 阅读1分钟

1.基本使用

使用很简单就是

mutableLiveData = MutableLiveData<String>()

//订阅消息
mutableLiveData.observe(this, Observer {
    Log.d(TAG, "data = $it")
})

发送数据

mutableLiveData.postValue("post data")

mutableLiveData.value = "set data"

注意数据是粘性的,后面会分析

post在子线程,set在主线程,其实post就是用handler放到主线程去set

private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
        setValue((T) newValue);
    }
};

2.封装

2.1.LiveDataBus

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;
    }


    //注册订阅者,(存入map)
    public synchronized <T> MutableLiveData<T> with(String key,Class<T> type,boolean sticky){
        if(!bus.containsKey(key)){
            if(sticky){
                bus.put(key, new MutableLiveData<Object>());
            }else {
                bus.put(key, new NonStickyMutableLiveData<Object>());
            }
        }
        return (MutableLiveData<T>) bus.get(key);
    }

}

使用

LiveDataBus.getInstance().with("msg",String.class,true).postValue("threadClick");
LiveDataBus.getInstance().with("msg", String.class,true)
        .observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.i("jett","bus->"+s);
            }
        });

2.2.非粘性Livedata


public class NonStickyMutableLiveData<T> extends MutableLiveData {

    private boolean stickFlag=false;

    @Override
    public void observe( LifecycleOwner owner,  Observer observer) {
        super.observe(owner, observer);
        if(!stickFlag) {
            hook(observer);
            stickFlag=true;
        }
    }

    //在这里去改变onChange的流程
    private void hook(Observer<? super T> observer) {
        try {
            //1.得到mLastVersion
            //获取到LiveData的类中的mObservers对象
            //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();
            //获取到mObservers对象的get方法   entry
            Method get = mObserversClass.getDeclaredMethod("get", Object.class);
            get.setAccessible(true);
            //执行get方法   mObservers.get(observer)
            Object invokeEntry=get.invoke(mObserversObject,observer);
            //定义一个空的对象
            Object observerWraper=null;
            if(invokeEntry!=null && invokeEntry instanceof Map.Entry){
                observerWraper=((Map.Entry)invokeEntry).getValue();//ObserverWrapper
            }
            if(observerWraper==null){
                throw new NullPointerException("observerWraper is null");
            }
            //得到ObserverWrapper的类对象  编译擦除问题会引起多态冲突所以用getSuperclass
            //TODO:getClass()返回对应的当前正在运行时的类所对应的对
            Class<?> superclass = observerWraper.getClass().getSuperclass();//mLastVersion
            Field mLastVersion = superclass.getDeclaredField("mLastVersion");
            mLastVersion.setAccessible(true);
            //2.得到mVersion
            Field mVersion = liveDataClass.getDeclaredField("mVersion");
            mVersion.setAccessible(true);
            //3.把mVersion的数据填入到mLastVersion中
            Object mVersionValue=mVersion.get(this);
            mLastVersion.set(observerWraper,mVersionValue);



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

3.源码分析

从两个关注点来看源码 1.死循环

liveData2 = new MutableLiveData<>();

liveData2.observe(this, new Observer<String>() {
    @Override
    public void onChanged(@Nullable String s) {
        Log.d("jett", "changed1 :" + s);
            liveData2.setValue("2");
    }
});

2.粘性liveData