使用 LiveDataBus 替代 EventBus

前言

引用官方 LiveData 介绍

LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.

译:LiveData 是可观察的数据持有者类。与常规的可观察对象不同,LiveData 具有生命周期感知功能,这意味着它遵循其他应用程序组件(例如 Activity ,Fragment 或 Service)的生命周期。这种意识确保 LiveData 仅更新处于活动生命周期状态的应用程序组件观察者。

LiveDataBus 和 EventBus 一样作为消息总线来使用,但实际上它算是一种模式,例如 RxBus 依托于 RxJava 的支持,仅用了不到 30 行代码便可实现一个新的消息总线;而 LiveDataBus 与之类似,依托于官方的 LiveData ,我们便可以自己写出一个消息总线,并且这个消息总线是具有生命周期感知能力的。

实现

object LiveDataBus {
    
    private val bus: MutableMap<String, MutableLiveData<Any>> = mutableMapOf()
    
    fun <T> with(key: String): MutableLiveData<T> {
        if (!bus.containsKey(key)) {
            bus[key] = MutableLiveData()
        }
        return bus[key] as MutableLiveData<T>
    }
}

嗯?!这样就完了?对的,使用 Kotlin 的话代码很少很简洁。首先这个 LiveDataBus 是一个单例,内部维护着一个可变 map ,这个 map 通过 key 值来返回相应的 LiveData 对象(如果没有这个对象的话就新建一个放进 map 再返回),而拿到这个对象就可以进行订阅或者发送消息了。

使用

发送消息

class MainActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        // ...
        
        // post
        LiveDataBus.with<String>("from_main")
      		.value = "From MainActivity."
        Thread {
            // 非主线程下使用 postValue
            LiveDataBus.with<String>("from_main")
            	.postValue("From MainActivity.")
        }.start
    }
}

订阅接收消息

class SecondActivity : AppCompatActivity() {
    
    private val observer = Observer<String> {
        Log.e(TAG, it)
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        // ...
        
        // 使用 observe 函数进行订阅的话,只会在宿主处于前台的状态才会进行回调,
        // 也就是如果 activity 被挂在后台了,那么消息会等到 activity 返回前台
        // 时再进行回调,这就是 LiveData 的生命周期感知能力带来的好处。
        LiveDataBus.with<String>("from_main")
        	.observe(this::getLifecycle) {
                Log.e(TAG, it)
            }
        
        // 但是如果我们希望即使 activity 不在前台也可以收到消息,这时就要使用
        // observeForever 这个函数了,使用这种方式订阅相当于忽略宿主的生命周期,
        // 任何时刻只要宿主还存活着,就一定会回调消息,缺点是需要自己注册与反注册。
        LiveDataBus.with<String>("from_main")
        	.observeForever(observer)
    }
    
    override fun onDestroy() {
        // ...
        LiveDataBus.with<String>("from_main")
       		.removeObserver(observer)
    }
}

真滴棒,仅仅用了几行代码就实现了一个消息总线,虽然是在 LiveData 的基础上将其发扬光大,但还是牛逼。于是开始投入使用,用着用着突然发现,好像有点不对劲,为什么我一订阅了就马上收到消息了,而且这个消息是在我订阅之前就发出的,坑爹啊......

问题

回顾一下上面遇到的问题,在订阅消息之后立刻就能收到订阅前发出的消息,这种属于粘性消息,用过 EventBus 的都知道,但问题是我们并不需要每次都接收粘性消息呀,如果消息不能准确接收的话那这个消息总线还是正宗的消息总线吗?

出现这个问题的原因: LiveData 内部的 mVersion 属性和 LiveData 内部类 ObserverWrapper 内部的 mLastVersion 属性之间会作比较,在订阅时只要 mLastVersion 小于 mVersion 就会强制推送最新的消息。LiveData 只要调用过 setValue 或者 postValue 都会使 mVersion++ ,而不管是 LiveData 或者是 LiveData.ObserverWrapper ,其 version 初始值都是 -1 ,只要用 LiveData 设置了值后它的 mVersion 值无论如何都大于 -1 了,这时再进行订阅就会马上收到最后发出的消息了。

源码分析

通过阅读源码可以发现,每当我们调用 LiveData.observe 函数时,内部都会创建一个 LiveData.LifecycleBoundObserver ,它是 ObserverWrapper 子类,并且实现了 GenericLifecycleObserver 接口,从名字上看可以知道这是一个绑定宿主生命周期的类。当 LifecycleOwner 的状态发生变化时,会调用 LiveData.LifecycleBoundObserver 的 onStateChanged 函数。

 

接着在 onStateChanged 函数内部进行判断,如果宿主不是 DESTROYED 状态就调用从 ObserverWrapper 继承过来的 activeStateChanged 函数,如果这个时候 ObserverWrapper 的状态是 active ,就继续调用 LiveData.dispatchingValue 函数。

 

LiveData.dispatchingValue 函数中又会调用 LiveData.considerNotify 函数。

 

LiveData.considerNotify 函数中,可以看到红框中的代码就是根本原因了,如果 ObserverWrapper 的 mLastVersion 小于 LiveData 的 mVersion ,就回调 onChanged() 函数,并且每个新的订阅者其 version 都是 -1 ,LiveData 一旦设置过 value 其 version 都是大于 -1 的,这样直接导致了每注册一个新的订阅者,这个订阅者马上就收到消息,即使这个发布消息的动作发生在订阅之前。

 

解决问题

通过阅读源码,终于弄明白了为什么会出现这种问题,那么既然出现了这个问题,就得想办法解决。根据上面的分析,只要在注册一个新的订阅者时把 ObserverWrapper 的 mLastVersion 设置成和 LiveData 的 mVersion 一样即可,看图。

 

我们直接从红框部分入手,LifecycleBoundObserver 是 ObserverWrapper 子类,创建完之后被放进了 mObservers ,mObservers 是 LiveData 的成员变量(SafeIterableMap<Observer<? super T>, ObserverWrapper>),实际上它是一个链表,从 mObservers 的源码中可以发现有一个 protected 的 get 函数,因此我们可以在调用 observe 的时候通过反射拿到 mObservers 中的 LifecycleBoundObserver ,再把它的 mLastVersion 设置成和 LiveData 一致。

而对于非生命周期感知的 observeForever 函数,函数内部生成的不是 LifecycleBoundObserver ,而是 AlwaysActivityObserver ,并且我们没有机会在 observeForever 调用完成后再去更改 AlwaysActiveObserver 的 mLastVersion ,因为再 observeForever 函数体内,回调就已经发生了,看下图。

 

对于 observeForever ,既然是在函数体中就发生消息回调的,那么可以写一个自己的 ObserverWrapper ,把真正的回调给包装起来。把我们自己的 ObserverWrapper 传给 observeForever ,然后在回调的前去检查调用栈,如果回调是 observeForever 引起的就不回调真正的订阅者。

改良后的 LiveDataBus

object LiveDataBus {

    private val bus: MutableMap<String, BusMutableLiveData<Any>> = mutableMapOf()

    fun <T> with(key: String): BusMutableLiveData<T> {
        if (!bus.containsKey(key)) {
            bus[key] = BusMutableLiveData()
        }
        return bus[key] as BusMutableLiveData<T>
    }

    class BusMutableLiveData<T> : MutableLiveData<T>() {
        private val observerMap: MutableMap<Observer<*>, Observer<*>> = mutableMapOf()

        fun observeSticky(
            owner: () -> Lifecycle,
            observer: (T) -> Unit
        ) {
            super.observe(owner, observer)
        }

        fun observeForeverSticky(observer: Observer<in T>) {
            super.observeForever(observer)
        }

        override fun observeForever(observer: Observer<in T>) {
            if (!observerMap.containsKey(observer)) {
                observerMap[observer] = ObserverWrapper(observer)
            }
            super.observeForever(observerMap[observer] as Observer<in T>)
        }

        override fun removeObserver(observer: Observer<in T>) {
            val realObserver: Observer<in T> =
                if (observerMap.containsKey(observer)) {
                    observerMap.remove(observer) as Observer<in T>
                } else {
                    observer
                }
            super.removeObserver(realObserver)
        }

        override fun observe(
            owner: LifecycleOwner,
            observer: Observer<in T>
        ) {
            super.observe(owner, observer)
            try {
                hook(observer)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        /**
         * 利用反射将 LiveData 的 mVersion 赋值给 ObserverWrapper 的 mLastVersion
         */
        @Throws(Exception::class)
        private fun hook(observer: Observer<*>) {
            // Get wrapper's version.
            val liveDataClass = LiveData::class.java
            // SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers
            val observersField = liveDataClass.getDeclaredField("mObservers")
            observersField.isAccessible = true
            val observers = observersField[this]
            val observersClass: Class<*> = observers.javaClass
            // It's mObservers's get method.
            val methodGet = observersClass.getDeclaredMethod("get", Any::class.java)
            methodGet.isAccessible = true
            val observerWrapperEntry = methodGet.invoke(observers, observer)
            var observerWrapper: Any? = null
            if (observerWrapperEntry is Map.Entry<*, *>) {
                // Now we got observerWrapper.
                observerWrapper = observerWrapperEntry.value
            }
            if (observerWrapper == null) {
                throw NullPointerException("Wrapper can not be null!")
            }
            val observerWrapperParentClass: Class<*>? = observerWrapper.javaClass.superclass
            val lastVersionField = observerWrapperParentClass!!.getDeclaredField("mLastVersion")
            lastVersionField.isAccessible = true
            // Get livedata's version.
            val versionField = liveDataClass.getDeclaredField("mVersion")
            versionField.isAccessible = true
            val version = versionField[this]
            // Set wrapper's version.
            lastVersionField[observerWrapper] = version
        }
    }

    private class ObserverWrapper<T>(val observer: Observer<T>) : Observer<T> {
        override fun onChanged(t: T) {
            if (isCallOnObserverForever()) {
                return
            }
            observer.onChanged(t)
        }

        private fun isCallOnObserverForever(): Boolean {
            val stackTrace = Thread.currentThread().stackTrace
            for (element in stackTrace) {
                if ("androidx.lifecycle.LiveData" == element.className
                    && "observeForever" == element.methodName
                ) {
                    return true
                }
            }
            return false
        }
    }
}

在这段源码中,用了 BusMutableLiveData 替换了 MutableLiveData ,并且增加了 2 个订阅粘性消息的函数,毕竟有时确实需要用到粘性消息,不可能赶尽杀绝,而原函数 observeobserveForever 则统一变成了非粘性订阅。

总结

可以看到相比第一版的 LiveDataBus ,改良版增加了许多代码,因为 version 机制,但反过来一想,如果没有这个 version ,我们一样还是要自己实现粘性订阅的功能,在 Android 帮我们实现了这个功能后,我们再自己增加非粘性订阅的功能,其实都差不多。

总结一下 LiveDataBus 的优缺点:

优点

  1. UI 和数据保持实时同步,因为 LiveData 采用观察者模式,只要数据发生改变就立刻通知订阅者。
  2. 避免内存泄漏,订阅者和生命周期绑定,当宿主销毁时订阅者能够马上清理自身数据。
  3. 解决 Configuration Change 问题,在屏幕发生旋转或宿主被回收重建时,能够第一时间接收到最新消息。
  4. 延续了传统消息总线的功能,如果宿主在非活跃状态下仍然需要进行消息回调,可以通过 observeForever 进行回调。
  5. 相比较 EventBus 和 RxBus 有着更好的支持,因为是官方组件,不需要额外进行依赖,减少 APK 包体大小。

缺点

  1. 订阅的时候有 Crash 风险,因为我们需要自己指定返回的消息类型,如果发布的消息类型与订阅时指定的消息类型不一致就直接 Crash 了。
  2. 如果需要和同事联调,因为这个消息类型会比较头疼,需要双方约定好每个 key 的消息类型,不然也是 Crash 。
  3. 其实就是上面 2 个缺点结合,增加了使用难度,在指定消息类型的时候需要谨慎。

Rxbus

在这里,还是先比较一下Rxbus

public class RxBus {

    private static volatile RxBus mDefaultInstance;

    private RxBus() {
    }

    public static RxBus getDefault() {
        if (mDefaultInstance == null) {
            synchronized (RxBus.class) {
                if (mDefaultInstance == null) {
                    mDefaultInstance = new RxBus();
                }
            }
        }
        return mDefaultInstance;
    }

    private final Subject<Object> _bus = PublishSubject.create().toSerialized();

    public void send(Object o) {
        _bus.onNext(o);
    }

    public Observable<Object> toObservable() {
        return _bus;
    }

    /**
     * 根据传递的 eventType 类型返回特定类型(eventType)的 被观察者
     *
     * @param eventType 事件类型
     * @param <T>
     * @return
     */
    public <T> Observable<T> toObservable(Class<T> eventType) {
        return _bus.ofType(eventType);
    }

    /**
     * 提供了一个新的事件,根据code进行分发
     *
     * @param code 事件code
     * @param o
     */
    public void post(int code, Object o) {
        _bus.onNext(new RxBusMessage(code, o));

    }

    /**
     * 根据传递的code和 eventType 类型返回特定类型(eventType)的 被观察者
     * 对于注册了code为0,class为voidMessage的观察者,那么就接收不到code为0之外的voidMessage。
     *
     * @param code      事件code
     * @param eventType 事件类型
     * @param <T>
     * @return
     */
    public <T> Observable<T> toObservable(final int code, final Class<T> eventType) {
        return _bus.ofType(RxBusMessage.class)
                .filter(new Predicate<RxBusMessage>() {
                    @Override
                    public boolean test(RxBusMessage rxBusMessage) throws Exception {
                        //过滤code和eventType都相同的事件
                        return rxBusMessage.getCode() == code && eventType.isInstance(rxBusMessage.getObject());
                    }
                }).map(new Function<RxBusMessage, Object>() {
                    @Override
                    public Object apply(RxBusMessage rxBusMessage) throws Exception {
                        return rxBusMessage.getObject();
                    }
                }).cast(eventType);
    }

    /**
     * 判断是否有订阅者
     */
    public boolean hasObservers() {
        return _bus.hasObservers();
    }

}

在RxJava中有个Subject类,它继承Observable类,同时实现了Observer接口,因此Subject可以同时担当观察者和被观察者的角色,使用PublishSubject来创建一个Subject对象PublishSubject只有被订阅后才会把接收到的事件立刻发送给观察者。

在需要接收事件的地方,订阅该Subject对象,之后如果Subject对象接收到事件,则会发射给该观察者,此时Subject对象充当被观察者的角色。

完成了订阅,在需要发送事件的地方将事件发送给之前被订阅的Subject对象,则此时Subject对象作为观察者接收事件,然后会立刻将事件转发给订阅该Subject对象的订阅者,以便观察者处理相应事件,到这里就完成了事件的发送与处理。

最后就是取消订阅的操作了,RxJava中,订阅操作会返回一个Disposable对象,调用Disposable.dispose()以便在合适的时机取消订阅,防止内存泄漏。

LiveDataBus(java)

public class LiveDataBusX {
    //存放订阅者
    private Map<String, BusMutiableLiveData<Object>> bus;
    private static LiveDataBusX liveDataBus = new LiveDataBusX();

    private LiveDataBusX() {
        bus = new HashMap();
    }
    public static LiveDataBusX getInstance() {
        return liveDataBus;
    }
    //注册订阅者
    public synchronized <T> BusMutiableLiveData<T> with(String key, Class<T> type) {
        if(!bus.containsKey(key)){
            bus.put(key,new BusMutiableLiveData<Object>());
        }
        return (BusMutiableLiveData<T>)bus.get(key);
    }

    public static class BusMutiableLiveData<T> extends MutableLiveData{
        @Override
        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
            super.observe(owner, observer);
            hook(observer);
        }

        private void hook(Observer<? super T> observer) {
            try{
                //1.得到mLastVersion
                Class<LiveData> liveDataClass=LiveData.class;
                Field mObserversFeild=liveDataClass.getDeclaredField("mObservers");
                mObserversFeild.setAccessible(true);
                //获取到这个成员变量的对象
                Object mObserversObject=mObserversFeild.get(this);
                //得到map对应的class对象
                Class<?> mObserversClass=mObserversObject.getClass();
                //需要执行get方法
                Method get=mObserversClass.getDeclaredMethod("get",Object.class);
                get.setAccessible(true);
                Object invokeEntry=get.invoke(mObserversObject,observer);

                Object observerWraper=null;

                if(invokeEntry!=null && invokeEntry instanceof Map.Entry){
                    observerWraper=((Map.Entry)invokeEntry).getValue();
                }
                if(observerWraper==null){
                    throw new NullPointerException("observerWraper is null!");
                }
                //得到ObserveWraper的类对象 ,编译擦除问题
                Class<?> superclass=observerWraper.getClass().getSuperclass();
                Field mLastVersion=superclass.getDeclaredField("mLastVersion");
                mLastVersion.setAccessible(true);
                //2.得到mVersion
               Field mVersion=liveDataClass.getDeclaredField("mVersion");
               mVersion.setAccessible(true);
                //3.mLastVersion填到mVersion中
                Object mVersionValue=mVersion.get(this);
                mLastVersion.set(observerWraper,mVersionValue);

            }catch(Exception e){
                e.printStackTrace();
            }

        }
    }

}

在使用这个LiveDataBus的过程中,订阅者会收到订阅之前发布的消息,这是不可接受的,在LifeData这篇文章中,讲述了原因,思路就是在把observerWraper的mLastVersion设置成个liveData的mVersion一样的值。


其他版本LivewDataBus

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 synchronized <T> Observable<T> with(String key, Class<T> type) {
        if (!bus.containsKey(key)) {
            bus.put(key, new BusMutableLiveData<>(key));
        }
        return (Observable<T>) bus.get(key);
    }

    public Observable<Object> with(String key) {
        return with(key, Object.class);
    }

    public interface Observable<T> {

       // void setValue(T value);

        void post(T value);

        void postDelay(T value, long delay);

        void postDelay(T value, long delay, TimeUnit unit);

        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer);

        void observeSticky(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer);

        void observeForever(@NonNull Observer<? super T> observer);

        void observeStickyForever(@NonNull Observer<T> observer);

        void removeObserver(@NonNull Observer<? super T> observer);
    }

    private static class BusMutableLiveData<T> extends MutableLiveData<T> implements Observable<T> {

        private class PostValueTask implements Runnable {
            private Object newValue;

            public PostValueTask(@NonNull Object newValue) {
                this.newValue = newValue;
            }

            @Override
            public void run() {
                setValue((T) newValue);
            }
        }

        @NonNull
        private final String key;
        private Map<Observer, Observer> observerMap = new HashMap<>();
        private Handler mainHandler = new Handler(Looper.getMainLooper());


        private BusMutableLiveData(String key) {
            this.key = key;
        }

        public boolean isMainThread() {
            return Looper.getMainLooper().getThread() == Thread.currentThread();
        }

        @Override
        public void post(T value) {
            if(isMainThread()) setValue(value);
            else  mainHandler.post(new PostValueTask(value));
        }

        @Override
        public void postDelay(T value, long delay) {
            mainHandler.postDelayed(new PostValueTask(value), delay);
        }

        @Override
        public void postDelay(T value, long delay, TimeUnit unit) {
            postDelay(value, TimeUnit.MILLISECONDS.convert(delay, unit));
        }

        @Override
        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
            SafeCastObserver<T> safeCastObserver = new SafeCastObserver(observer);
            //保存LifecycleOwner的当前状态
            Lifecycle lifecycle = owner.getLifecycle();
            Lifecycle.State currentState = lifecycle.getCurrentState();
            int observerSize = getLifecycleObserverMapSize(lifecycle);
            boolean needChangeState = currentState.isAtLeast(Lifecycle.State.STARTED);
            if (needChangeState) {
                //把LifecycleOwner的状态改为INITIALIZED
                setLifecycleState(lifecycle, Lifecycle.State.INITIALIZED);
                //set observerSize to -1,否则super.observe(owner, observer)的时候会无限循环
                setLifecycleObserverMapSize(lifecycle, -1);
            }
            super.observe(owner, safeCastObserver);
            if (needChangeState) {
                //重置LifecycleOwner的状态
                setLifecycleState(lifecycle, currentState);
                //重置observer size,因为又添加了一个observer,所以数量+1
                setLifecycleObserverMapSize(lifecycle, observerSize + 1);
                //把Observer置为active
                hookObserverActive(safeCastObserver, true);
            }
            //更改Observer的version
            hookObserverVersion(safeCastObserver);
        }

        public void observeSticky(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
            super.observe(owner, new SafeCastObserver<>(observer));
        }

        @Override
        public void observeForever(@NonNull Observer<? super T> observer) {
            if (!observerMap.containsKey(observer)) {
                observerMap.put(observer, new ObserverWrapper(observer));
            }
            super.observeForever(observerMap.get(observer));
        }

        public void observeStickyForever(@NonNull Observer<T> observer) {
            super.observeForever(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);
            if (!hasObservers()) {
                LiveDataBus.get().bus.remove(key);
            }
        }

        private void setLifecycleObserverMapSize(Lifecycle lifecycle, int size) {
            if (lifecycle == null) {
                return;
            }
            if (!(lifecycle instanceof LifecycleRegistry)) {
                return;
            }
            try {
                Field observerMapField = LifecycleRegistry.class.getDeclaredField("mObserverMap");
                observerMapField.setAccessible(true);
                Object mObserverMap = observerMapField.get(lifecycle);
                Class<?> superclass = mObserverMap.getClass().getSuperclass();
                Field mSizeField = superclass.getDeclaredField("mSize");
                mSizeField.setAccessible(true);
                mSizeField.set(mObserverMap, size);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private int getLifecycleObserverMapSize(Lifecycle lifecycle) {
            if (lifecycle == null) {
                return 0;
            }
            if (!(lifecycle instanceof LifecycleRegistry)) {
                return 0;
            }
            try {
                Field observerMapField = LifecycleRegistry.class.getDeclaredField("mObserverMap");
                observerMapField.setAccessible(true);
                Object mObserverMap = observerMapField.get(lifecycle);
                Class<?> superclass = mObserverMap.getClass().getSuperclass();
                Field mSizeField = superclass.getDeclaredField("mSize");
                mSizeField.setAccessible(true);
                return (int) mSizeField.get(mObserverMap);
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }

        private void setLifecycleState(Lifecycle lifecycle, Lifecycle.State state) {
            if (lifecycle == null) {
                return;
            }
            if (!(lifecycle instanceof LifecycleRegistry)) {
                return;
            }
            try {
                Field mState = LifecycleRegistry.class.getDeclaredField("mState");
                mState.setAccessible(true);
                mState.set(lifecycle, state);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private Object getObserverWrapper(@NonNull Observer<T> observer) throws Exception {
            Field fieldObservers = LiveData.class.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();
            }
            return objectWrapper;
        }

        private void hookObserverVersion(@NonNull Observer<T> observer) {
            try {
                //get wrapper's version
                Object objectWrapper = getObserverWrapper(observer);
                if (objectWrapper == null) {
                    return;
                }
                Class<?> classObserverWrapper = objectWrapper.getClass().getSuperclass();
                Field fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion");
                fieldLastVersion.setAccessible(true);
                //get livedata's version
                Field fieldVersion = LiveData.class.getDeclaredField("mVersion");
                fieldVersion.setAccessible(true);
                Object objectVersion = fieldVersion.get(this);
                //set wrapper's version
                fieldLastVersion.set(objectWrapper, objectVersion);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private void hookObserverActive(@NonNull Observer<T> observer, boolean active) {
            try {
                //get wrapper's version
                Object objectWrapper = getObserverWrapper(observer);
                if (objectWrapper == null) {
                    return;
                }
                Class<?> classObserverWrapper = objectWrapper.getClass().getSuperclass();
                Field mActive = classObserverWrapper.getDeclaredField("mActive");
                mActive.setAccessible(true);
                mActive.set(objectWrapper, active);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static class ObserverWrapper<T> implements Observer<T> {

        @NonNull
        private final Observer<T> observer;

        ObserverWrapper(@NonNull Observer<T> observer) {
            this.observer = observer;
        }

        @Override
        public void onChanged(@Nullable T t) {
            if (isCallOnObserve()) {
                return;
            }
            try {
                observer.onChanged(t);
            } catch (ClassCastException e) {
                e.printStackTrace();
            }
        }

        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;
        }
    }

    private static class SafeCastObserver<T> implements Observer<T> {

        @NonNull
        private final Observer<T> observer;

        SafeCastObserver(@NonNull Observer<T> observer) {
            this.observer = observer;
        }

        @Override
        public void onChanged(@Nullable T t) {
            try {
                observer.onChanged(t);
            } catch (ClassCastException e) {
                e.printStackTrace();
            }
        }
    }

    public static <T> Observable<T> get(@NonNull String key, @NonNull Class<T> type) {
        return get().with(key, type);
    }


    public static <T> Observable<T> get(@NonNull String key) {
        return (Observable<T>)get(key, Object.class);
    }

    public static <T > Observable<T> get(@NonNull Class<T> eventType) {
        return get(eventType.getName(), eventType);
    }


}

上述代码实现了一个通信总线的全部功能,并且还具有生命周期感知功能,使用起来也及其简单,具体使用如下。

注册订阅:

     LiveDataBus.get("test", Boolean.class)
                .observe(this, new Observer<Boolean>() {
                    @Override
                    public void onChanged(Boolean aBoolean) {

                    }
                });

注意:observe仅更新处于活动生命周期状态的应用程序组件观察者,如果需要不受生命周期的影响,只要数据更新就会收到通知可以使用observeForever,这意味着给定的观察者将接收所有事件,并且永远不会被自动删除。需要手动调用removeObserver(Observer)来停止这个LiveData。

发送消息

  LiveDataBus.get("test").post(true);

 注意:livedata的setValue只可在主线程下使用,多线程下可使用postValue,当然主线程也可以使用这个。这里实现了自己的post方法,统一判断当前所在线程,调用合适的方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值