https://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&mid=2651748475&idx=4&sn=8feb14dd49ce79726ecf12eb6c243740&chksm=bd12a1368a652820df7c556182d3494d84ae38d4aee4e84c48c227aa5083ebf2b1a0150cf1b5&scene=38#wechat_redirect
LiveDataBus
LiveDataBus是基于LiveData实现的类似EventBus的消息通讯框架,它是基于LiveData实现的.
LiveDataBus的长处
- LiveData具有的这种可观察性和生命周期感知的本事
- 利用者不消表现调用反注册方法,由于LiveData具有生命周期感知本事,以是LiveDataBus只须要调用注册回调方法,而不须要表现的调用反注册方法。
- LiveDataBus的实现极其简单,相对EventBus复杂的实现,LiveDataBus只须要一个类就可以实现。
- LiveDataBus可以减小APK包的巨细,由于LiveDataBus只依靠Android官方Android Architecture Components组件的LiveData,没有其他依靠,本身实现只有一个类。
LiveDataBus的构成
- 消息
- 消息可以是任何的Object,可以界说差异范例的消息,如Boolean、String。也可以界说自界说范例的消息。
- 消息通道
- LiveData饰演了消息通道的脚色,差异的消息通道用差异的名字区分,名字是String范例的,可以通过名字获取到一个LiveData消息通道。
- 消息总线
- 消息总线通过单例实现,差异的消息通道存放在一个HashMap中。
- 订阅
- 订阅者通过getChannel获取消息通道,然后调用observe订阅这个通道的消息。
- 发布
- 发布者通过getChannel获取消息通道,然后调用setValue大概postValue发布消息。
LiveDataBus的详细实现
public final class LiveDataBus { private final Map<String, BusMutableLiveData<Object>> bus; private LiveDataBus() { bus = new HashMap<>(); } private static class SingletonHolder { private static final LiveDataBus DEFAULT_BUS = new LiveDataBus(); } public static LiveDataBus get() { return SingletonHolder.DEFAULT_BUS; } public <T> MutableLiveData<T> with(String key, Class<T> type) { if (!bus.containsKey(key)) { bus.put(key, new BusMutableLiveData<>()); } return (MutableLiveData<T>) bus.get(key); } public MutableLiveData<Object> with(String key) { return with(key, Object.class); } 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 ("android.arch.lifecycle.LiveData".equals(element.getClassName()) && "observeForever".equals(element.getMethodName())) { return true; } } } return false; } } private static class BusMutableLiveData<T> extends MutableLiveData<T> { private Map<Observer, Observer> observerMap = new HashMap<>(); @Override public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) { super.observe(owner, observer); try { hook(observer); } catch (Exception e) { e.printStackTrace(); } } @Override public void observeForever(@NonNull Observer<T> observer) { if (!observerMap.containsKey(observer)) { observerMap.put(observer, new ObserverWrapper(observer)); } super.observeForever(observerMap.get(observer)); } @Override public void removeObserver(@NonNull Observer<T> observer) { Observer realObserver = null; if (observerMap.containsKey(observer)) { realObserver = observerMap.remove(observer); } else { realObserver = observer; } super.removeObserver(realObserver); } private void hook(@NonNull Observer<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); } }}利用方法
LiveDataBus.get() .with("tag", String.class) .observe(this, new Observer<String>() { @Override public void onChanged(@Nullable String s) { } });
LiveDataBus.get().with("tag").setValue(str); |