美文网首页
LiveData 实现消息总线,包括黏性消息

LiveData 实现消息总线,包括黏性消息

作者: 东土也 | 来源:发表于2022-03-07 09:34 被阅读0次
package com.slowtd.basicslib.tbus

import androidx.lifecycle.*

object TDataBus {
    private val eventMap = mutableMapOf<String, LiveData<*>>()

    /**
     * @param eventName 接受消息名称,自定义,一种消息名称对应一种格式的消息
     */
    fun <T> with(eventName : String) : BusLiveData<T>{
        var liveData = eventMap[eventName]
        if(liveData == null){
            liveData = BusLiveData<T>()
            eventMap[eventName] = liveData
        }
        return liveData as BusLiveData<T>
    }



    class BusLiveData<T> : LiveData<T>(){
        private var mData : T? = null
        private var mVersion = -1
        public override fun postValue(value: T) {
            //mVersion++
            super.postValue(value)
        }

        public override fun setValue(value: T) {
            mVersion++
            super.setValue(value)
        }
        /**
         * 对于粘性观察者,只有发送粘性消息才会在注册后收到消息,若发送普通消息,粘性观察者也不会在消息发送后注册收到消息
         */
        fun postStickyValue(value: T){
            mData = value
            super.postValue(value)
        }

        /**
         * 对于粘性观察者,只有发送粘性消息才会在注册后收到消息,若发送普通消息,粘性观察者也不会在消息发送后注册收到消息
         */
        fun setStickyValue(){
            mData = value
            mVersion++
            super.setValue(value)
        }

        override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
            observerSticky(owner, observer, false)
        }

        fun observerSticky(owner: LifecycleOwner, observer: Observer<in T>, sticky : Boolean = false){
            val busObserver = BusObserver<T>(this, observer = observer, sticky)
//            owner.lifecycle.addObserver(object : LifecycleEventObserver{
//                override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
//                    if(event == Lifecycle.Event.ON_DESTROY){
//                        eventMap.remove(eventName)
//                    }
//                }
//
//            })
            super.observe(owner, busObserver)
        }

        private class  BusObserver<T>(val liveData: BusLiveData<T>, val observer: Observer<in T>, val sticky: Boolean = false) : Observer<T>{
            var mVersion = -1
            var init = true
            override fun onChanged(t: T) {
                /**
                 * TDataBus.with<String>("Main").postValue("Hello")
                 * TDataBus.with<String>("Main").observerSticky(this, Observer {
                 * Log.e("MainActivity", it)
                 * }, true)
                 * 如果使用postValue后立即注册观察者,由于postValue是通过handler去调用setValue
                 * ,会导致观察者的mVersion得不到同步,所以在第一次观察者调用的时候同步version,从而达到粘性消息取消的目的
                 */
                if(init){
                    mVersion = liveData.mVersion
                    init = false
                }
                if(mVersion >= liveData.mVersion){
                    if(sticky && liveData.mData != null){
                        observer.onChanged(liveData.mData)
                    }
                    return
                }
                observer.onChanged(t)
                mVersion = liveData.mVersion
            }


        }
    }

}

代码很简单,主要就是实现LiveData, Observer,自己维护LiveData和观察者中的version。
用法

//发送黏性消息,接受粘性消息
TDataBus.with<String>("Main").postStickyValue("Hello")
        TDataBus.with<String>("Main").observerSticky(this, Observer {
            Log.e("MainActivity", it)
        }, true)

TDataBus.with<String>("test").setValue("OnClick")
 TDataBus.with<String>("test").observe(this, Observer {
            Log.e(TAG, it)
        })

相关文章

网友评论

      本文标题:LiveData 实现消息总线,包括黏性消息

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