rxbus
优点 效率高,无内存泄露、UI和实时数据保持一致
缺点: 依赖包 2.2M 比较大
EventBus
优点 使用简单、UI和实时数据保持一致
缺点: 混淆问题,无法感知生命周期 很难追踪到发布源
LiveDataBus
优点:
UI和实时数据保持一致
避免内存泄露,内部实现
不会在产生由于Activity处于stop状态而引起崩溃
不需要解决生命周期带来的问题
实时数据刷新
解决Configuration chanage问题
使用系统api
liveData 是一个数据持有类,持有数据并且这个数据能被观察者所监听到,而且他是和lifecycle绑定,具有声明周期感知,解决内存泄露和引用问题
所有的框架,如果和声明周期相关,里面肯定有lifecycle
lifecycle 是android 官方退出的官方架构之一,他是具有生命周期感知的,不单能够监听Activity和Fragment的生命周期,还能回调相应的方法,同时他能够实时的获取当前Activity和fragment的状态
image.pngLiveDataBus使用中有个缺点,在A页面发送消息,再进入B页面,这个时候B页面还能接受到消息,是个错误,
因为从事件上来说,需要注册后,再发送,
发送一个事件
# MutableLiveData
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value); //调用父类
}
}
# LiveData
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
// 发现是个线程
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
# LiveData
// 找到线程方法
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue); // 通过它来赋值
}
};
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++; // 发现mVersion ++ 也就是发送一个事件 增加
mData = value;
dispatchingValue(null);
}
通过源码也就明白 mVersion 和 mLastVersion 开始都是0,发送一个事件mVersion +1 ,
下面,通过hook 来改变
在LiveDataBus中,也就是通过onChanged方法来接收监听,我们可以在接收到事件后,拦截监听,
通过代码发现 observer.mLastVersion >= mVersion 这块如果大于或等于就可以拦截,退出这个方法,从而让observer.mObserver.onChanged((T) mData);不能执行,起到拦截的作用
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return; // 可以在这里进行hook 让他们相等
}
observer.mLastVersion = mVersion;
// 进行发送 onChanged 事件
observer.mObserver.onChanged((T) mData);
}
mVersion 就是LiveData 的成员变量,可以直接获取到
mLastVersion 是ObserverWrapper的成员变量
发现considerNotify方法是通过for循环遍历mObservers,我们找到mObservers
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
// 通过遍历 执行这个方法
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
发现 SafeIterableMap 的value 又是 Entry
# SafeIterableMap
protected Entry<K, V> get(K k) {
Entry<K, V> currentNode = mStart;
while (currentNode != null) {
if (currentNode.mKey.equals(k)) {
break;
}
currentNode = currentNode.mNext;
}
return currentNode;
}
所以我们需要先找到mObservers,再获取其中的Entry,就获得到ObserverWrapper,从而改变mLastVersion,需要注意得到的ObserverWrapper是子类LifecycleBoundObserver,需要获取父类
下面是完整代码
public class LiveDataBus {
private static final String TAG = "LiveDataBus";
private static LiveDataBus liveDataBus = new LiveDataBus();
// 创建一个容器 装载所有的订阅者
private Map<String, BusMutableLiveData<Object>> bus;
private LiveDataBus() {
bus = new HashMap<>();
}
public static LiveDataBus getInstance() {
return liveDataBus;
}
public synchronized <T> BusMutableLiveData<T> with(String key, Class<T> type) {
if (!bus.containsKey(key)) {
bus.put(key, new BusMutableLiveData<Object>());
}
return (BusMutableLiveData<T>) bus.get(key);
}
public static class BusMutableLiveData<T> extends MutableLiveData<T> {
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
super.observe(owner, observer);
try {
hook(observer);
} catch (Exception e) {
e.printStackTrace();
}
}
private void hook(Observer observer) throws Exception {
// 获取 LiveData 的类对象
Class<LiveData> liveDataClass = LiveData.class;
// 获取 mVersion 对象
Field mVersionField = liveDataClass.getDeclaredField("mVersion");
mVersionField.setAccessible(true);
// 获取 mObservers 对象
Field mObserversField = liveDataClass.getDeclaredField("mObservers");
mObserversField.setAccessible(true);
// 通过get 能获取到mObservers这个成员变量
// SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers
// 因为MutableLiveData 是 LiveData的子类,所以直接this 就能获取
Object mObservers = mObserversField.get(this);
// 获取map 的get方法 ,map 获取的value 是Object类型
Method get = mObservers.getClass().getDeclaredMethod("get", Object.class);
get.setAccessible(true);
// 执行get, mObservers 里面就是 Observer 和 ObserverWrapper,所以直接传递observer
Object invoke = get.invoke(mObservers, observer);
Object observerWrapper = null;
// 如果 执行结果不为空 并且也是Entry类型,说明结果对的
if (invoke != null && invoke instanceof Map.Entry) {
observerWrapper = ((Map.Entry) invoke).getValue();
}
if (observerWrapper == null) {
throw new NullPointerException();
}
// 这个时候获取到mObservers 的value 再来改变mLastVersion 的值
Class<?> observerWrapperClass = observerWrapper.getClass();
Log.i(TAG, "observerWrapperClass: "+observerWrapperClass);
// 发现获取的类类型 是 LifecycleBoundObserver,是 ObserverWrapper 子类,所以要 getSuperclass
Field mLastVersion = observerWrapperClass.getSuperclass().getDeclaredField("mLastVersion");
mLastVersion.setAccessible(true);
// 得到 mVersionField 的值
Object o = mVersionField.get(this);
// 将mVersionField的值 付给 mLastVersion
mLastVersion.set(observerWrapper, o);
}
}
使用
通过postValue发送事件,可以传递事件名,和事件类型,注意发送事件名对应的类型 要和接收的类型一致
# 发送
LiveDataBus.getInstance().with("wx", String.class).postValue("Two");
# 接收
LiveDataBus.getInstance().with("wx",String.class).observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.i(TAG, "onChanged: "+s);
}
});
网友评论