最近使用Rxbus发现升级到33版本的时候,会出现报黄色,看着很不舒服。然后就想着找找替换的方案。查找了蛮多资料。发现版本大部分都是大同小异。就如下的链接的三个版本。第一个就是简单实现类型。也是之前Rxbus早期的原型。再就是后面我用来改良的版本。
但是跟之前用的Rxbus又有点不一样。因为原先都是习惯了的懒人写法。所以就用当前的类名(XXX.getClass().getSimpleName())来替代需要一直定义的订阅键值。好吧,话不多说。直接上源码:
/**
* LiveDataBus 数据交互帮助类
*
* <p>
* Created by
* Change
*/
public class LiveDataBus {
public static final Map<String, BusMutableLiveData<Object>> bus = new HashMap<>();
public static synchronized <T> MutableLiveData<T> toObservable(Class<T> type){
String key = type.getSimpleName();
if (!bus.containsKey(key)){
bus.put(key, new BusMutableLiveData<>());
}
return (MutableLiveData<T>) bus.get(key);
}
public static void post(Object type){
String key = type.getClass().getSimpleName();
if (!bus.containsKey(key)){
bus.put(key, new BusMutableLiveData<>());
}
Objects.requireNonNull(bus.get(key)).postValue(type);
}
private static class ObserverWrapper<T> implements Observer<T> {
private Observer<T> observer;
public ObserverWrapper(Observer<T> observer) {
this.observer = observer;
}
@Override
public void onChanged(@Nullable T t) {
if (observer != null) {
if (isCallOnObserve()) {
return;
}
observer.onChanged(t);
}
}
private boolean isCallOnObserve() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
if (stackTrace != null && stackTrace.length > 0) {
for (StackTraceElement element : stackTrace) {
if ("androidx.lifecycle.LiveData".equals(element.getClassName()) &&
"observeForever".equals(element.getMethodName())) {
return true;
}
}
}
return false;
}
}
public static class BusMutableLiveData<T> extends MutableLiveData<T> {
private Map<Observer, Observer> observerMap = new HashMap<>();
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
super.observe(owner, observer);
try {
hook(observer);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void observeForever(@NonNull Observer<? super T> observer) {
if (!observerMap.containsKey(observer)) {
observerMap.put(observer, new ObserverWrapper(observer));
}
super.observeForever(Objects.requireNonNull(observerMap.get(observer)));
}
@Override
public void removeObserver(@NonNull Observer<? super T> observer) {
Observer realObserver = null;
if (observerMap.containsKey(observer)) {
realObserver = observerMap.remove(observer);
} else {
realObserver = observer;
}
super.removeObserver(realObserver);
}
private void hook(@NonNull Observer<? super T> observer) throws Exception {
//get wrapper's version
Class<LiveData> classLiveData = LiveData.class;
Field fieldObservers = classLiveData.getDeclaredField("mObservers");
fieldObservers.setAccessible(true);
Object objectObservers = fieldObservers.get(this);
Class<?> classObservers = objectObservers.getClass();
Method methodGet = classObservers.getDeclaredMethod("get", Object.class);
methodGet.setAccessible(true);
Object objectWrapperEntry = methodGet.invoke(objectObservers, observer);
Object objectWrapper = null;
if (objectWrapperEntry instanceof Map.Entry) {
objectWrapper = ((Map.Entry) objectWrapperEntry).getValue();
}
if (objectWrapper == null) {
throw new NullPointerException("Wrapper can not be bull!");
}
Class<?> classObserverWrapper = objectWrapper.getClass().getSuperclass();
Field fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion");
fieldLastVersion.setAccessible(true);
//get livedata's version
Field fieldVersion = classLiveData.getDeclaredField("mVersion");
fieldVersion.setAccessible(true);
Object objectVersion = fieldVersion.get(this);
//set wrapper's version
fieldLastVersion.set(objectWrapper, objectVersion);
}
}
}
使用方法:
注意:observe仅更新处于活动生命周期状态的应用程序组件观察者,如果需要不受生命周期的影响,只要数据更新就会收到通知可以使用observeForever,这意味着给定的观察者将接收所有事件,并且永远不会被自动删除。需要手动调用removeObserver(Observer)来停止这个LiveData。
注册订阅:
// 接收不受生命周期的影响
LiveDataBus.toObservable(TokenEvent.class).observeForever(result -> {// 做退出登录的操作
exit();
LoginActivity.startActivity(this);
});
// 接收受生命周期的影响
LiveDataBus.toObservable(TokenEvent.class).observe(this, result -> {// 做退出登录的操作
exit();
LoginActivity.startActivity(this);
});
发送消息:
LiveDataBus.post(new TokenEvent());
总结:
实践是检验真理的唯一标准----古人说的话没错。最后,希望能帮助到需要的人。有问题请指正,谢谢!下面是查阅的相关资料。有需要的可以去看看。原理什么的可以去了解一下下。我就不去复述照搬了。大家互相学习吧!共勉