美文网首页Android开发Android技术进阶Android-Jetpack
基于LiveData,优雅的打造一款事件总线LiveDataBu

基于LiveData,优雅的打造一款事件总线LiveDataBu

作者: BugRui | 来源:发表于2020-05-18 17:13 被阅读0次

    为什么要用LiveData实现事件总线呢?

    LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

    LiveData 具有生命周期感知能力,确保界面符合数据状态,不会发生内存泄露,不会因 Activity停止而导致崩溃,不再需要手动处理生命周期,数据始终保持最新状态

    LiveData 我就不多做介绍了,LiveData已经有很多,很详细的文章

    接下来谈谈如何使用LiveData实现事件总线

    定义一个HashMap用于保存不同的消息通道
     private val liveDataMap = HashMap<String, MutableLiveData<Any?>>()
    
    使用LiveData实现事件总线的难点:
    由于LiveData在每次配置更改(如设备旋转)而重新创建了 Activity 或Fragment,
    LiveData会立即接收最新的可用数据,这就意味着会收到重复的事件。
    
    解决方案:

    为了避免收到重复的事件,这里我使用的解决方案是每次都new一个新的MutableLiveData替换原来的MutableLiveData,这样一来,每次配置更改的时候都会生成一个新的MutableLiveData,也就不会收到上一个MutableLiveData的消息,但是多处订阅的时候需要使用不同的tag,否则只有最后一个订阅的地方收到

     fun with(tag: String): LiveData<Any?>? {
         liveDataMap.put(tag,MutableLiveData())
         return liveDataMap[tag]
     }
    
    订阅事件,仅更新处于活动生命周期状态的应用程序组件观察者
    
    LiveDataBus.with(tag).observe(this, Observer {
             //收到消息
    })
    
    

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

    
    /**
         * Adds the given observer to the observers list. This call is similar to
         * {@link LiveData#observe(LifecycleOwner, Observer)} with a LifecycleOwner, which
         * is always active. This means that the given observer will receive all events and will never
         * be automatically removed. You should manually call {@link #removeObserver(Observer)} to stop
         * observing this LiveData.
         * While LiveData has one of such observers, it will be considered
         * as active.
         * <p>
         * If the observer was already added with an owner to this LiveData, LiveData throws an
         * {@link IllegalArgumentException}.
         *
         * @param observer The observer that will receive the events
         */
        @MainThread
        public void observeForever(@NonNull Observer<? super T> observer) {
            assertMainThread("observeForever");
            AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
            ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
            if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
                throw new IllegalArgumentException("Cannot add the same observer"
                        + " with different lifecycles");
            }
            if (existing != null) {
                return;
            }
            wrapper.activeStateChanged(true);
        }
    
    使用observeForever 订阅,不受生命周期的影响,只要数据更新就会收到通知
    
    LiveDataBus.with(tag).observeForever(this, Observer {
             //收到消息
    })
    
    
    事件的发送
    
    fun send(tag: String, t: Any? = null) {
        if (!liveDataMap.containsKey(tag) ) return
        liveDataMap[tag]?.postValue(t)
    }
    
    // 发送
    LiveDataBus.send(tag)
    
    
    最后,附上完整的代码
    object LiveDataBus {
    
        private val liveDataMap = HashMap<String, MutableLiveData<Any?>>()
    
    
        fun with(tag: String): LiveData<Any?>? {
            liveDataMap.put(tag,MutableLiveData())
            return liveDataMap[tag]
        }
    
       
        fun send(tag: String, t: Any? = null) {
            if (!liveDataMap.containsKey(tag) ) return
            liveDataMap[tag]?.postValue(t)
        }
    
    }
    
    

    LiveDataBus 的源码可以直接拷贝使用,也可以前往作者的 GitHub 仓库查看下载:
    https://github.com/BugRui/LiveDataBus

    相关文章

      网友评论

        本文标题:基于LiveData,优雅的打造一款事件总线LiveDataBu

        本文链接:https://www.haomeiwen.com/subject/fqienhtx.html