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