Android LiveData 解决数据倒灌
为什么使用LiveData
还在使用evenBus、RxBus、Handler通信?
1.使用Handler通信容易造成内存泄漏,因为当Activity销毁后,handler还持有activity、context等的引用 就容易导致内存泄漏等问题。
2.使用evenBus、RxBus,混淆代码的时候容易接收不到消息。
3.livedata是Google提供的,不是第三方框架,jetpack组件的一部分,可单独使用通信,完美替代handle,evenBus等。
LiveData优势:
我就不用google官方的描述了,livedata优势:
1.不会导致内存泄漏;
2.组件通信;
3.数据共享;
基本使用
1.引入相关的依赖包
// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:1.1.0"
// alternatively, just ViewModel
implementation "android.arch.lifecycle:viewmodel:1.1.0"
// alternatively, just LiveData
implementation "android.arch.lifecycle:livedata:1.1.0"
2.livedata的使用需要封装在一个livedataBus的类里面,获取MyMutableLiveData:
public<T> MyMutableLiveData<T> with(String key,Class<T> clazz){
if(!map.containsKey(key)){
map.put(key,new MyMutableLiveData<Object>());
}
return (MyMutableLiveData<T>) map.get(key);
}
public MyMutableLiveData<Object> with(String key){
return with(key,Object.class);
}
3.解决数据倒灌,其实就是通过hook修改livedata源码observer.mLastVersion的值,使得if (observer.mLastVersion >= mVersion)成立,就不会导致没有注册观察者,还能接收到消息。
/**
* hook的执行时间?注册观察者的时候
* @param <T>
*/
public static class MyMutableLiveData<T> extends MutableLiveData<T>{
//目的:使得在observe被调用的时候,能够保证 if (observer.mLastVersion >= mVersion) (livedata源码里面的)成立
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
super.observe(owner, observer);
try {
hook(observer);
} catch (Exception e) {
e.printStackTrace();
}
}
public void observeSticky(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer){
super.observe(owner, observer);
}
/**要修改observer.mLastVersion的值那么思考:(逆向思维)
* mLastVersion-》observer-》iterator.next().getValue()-》mObservers
* 反射使用的时候,正好相反
*
* mObservers-》函数(iterator.next().getValue())-》observer-》mLastVersion
* 通过hook,将observer.mLastVersion = mVersion
* @param observer
* @throws Exception
*/
private void hook(Observer<? super T> observer) throws Exception {
Class<LiveData> liveDataClass = LiveData.class;
Field fieldmObservers = liveDataClass.getDeclaredField("mObservers");
fieldmObservers.setAccessible(true);
Object mObservers = fieldmObservers.get(this);
Class<?> mObserversClass = mObservers.getClass();
Method methodget = mObserversClass.getDeclaredMethod("get", Object.class);
methodget.setAccessible(true);
Object entry = methodget.invoke(mObservers, observer);
Object observerWrapper = ((Map.Entry) entry).getValue();
Class<?> mObserver = observerWrapper.getClass().getSuperclass();//observer
Field mLastVersion = mObserver.getDeclaredField("mLastVersion");
mLastVersion.setAccessible(true);
Field mVersion = liveDataClass.getDeclaredField("mVersion");
mVersion.setAccessible(true);
Object mVersionObject = mVersion.get(this);
mLastVersion.set(observerWrapper,mVersionObject);
}
}
下一篇:自定义livedata,使用自己的livedata通信。