LiveDataBus

具体参考

https://www.cnblogs.com/meituantech/p/9376449.html

观察者模式

多个果商订阅了某个果农的果子,果子熟了告诉我。

几天后果子熟了,果农一个个通知果商来拿货

发布/订阅模式

发布者只负责把信息发布到调度中心,至于这信息有没有人处理,怎么样处理,则不关心。

 

附加上代码

/**
 * 替换 EventBus  RxBus
 * 最优一点  自动跟组件生命周期绑定一起  可以参考Lifecycle
 *
 * 观察者模式  1对多的关系    观察者A -》 订阅 -》  被观察者B
 *                                  《- 触发事件《-
 *
 *
 * 发布者只管发布消息到调度中心  这个消息是否需要  不需要管
 * 发布订阅模式  1对多的关系   订阅者A  -》 订阅 -》  调度中心B    <=发布消息<=  发布者
 *                                   《- 触发事件《-
 * lahm
 */
class LiveDataBus {
    private var bus: HashMap<String, BusMutableLiveData<Any>>? = null

    constructor() {
        bus = HashMap()
    }

    //泛型方法  type主要用于取泛型类型
    fun <T> with(key: String, type: Class<T>, isViscidity: Boolean): MutableLiveData<T> {
        if (bus == null) {
            throw NullPointerException("bus can not be null!")
        }
        if (!bus!!.containsKey(key)) {
            bus!![key] = BusMutableLiveData(isViscidity)
        }
        return bus!![key] as (MutableLiveData<T>)
    }

    fun <T> with(key: String, type: Class<T>): MutableLiveData<T> {
        return with(key, type, false)
    }

    //普通
    fun with(key: String): MutableLiveData<Any> {
        return with(key, Any::class.java, false)
    }

    //粘性
    fun with(key: String, isViscidity: Boolean): MutableLiveData<Any> {
        return with(key, Any::class.java, isViscidity)
    }

    companion object {
        val KEY_GOTO_HOME = "go_home"//跳转首页逻辑

        fun get(): LiveDataBus {//单例的另外一种写法
            return Companion.SingletonHolder.DEFAULT_BUS
        }

        class SingletonHolder {
            companion object {
                val DEFAULT_BUS = LiveDataBus()
            }
        }

        class ObserverWrapper<T>(val observer: Observer<T>?) : Observer<T> {

            override fun onChanged(t: T?) {
                if (observer != null) {
                    if (isCallOnObserve()) {
                        return
                    }
                    observer.onChanged(t)
                }
            }

            fun isCallOnObserve(): Boolean {
                val stackTrace = Thread.currentThread().stackTrace
                if (stackTrace != null && stackTrace.isNotEmpty()) {
                    for (element in stackTrace) {
                        if ("android.arch.lifecycle.LiveData" == element.className && "observeForever" == element.methodName) {
                            return true
                        }
                    }
                }
                return false
            }
        }

        class BusMutableLiveData<T>() : MutableLiveData<T>() {
            private val observerMap: HashMap<Observer<T>, Observer<T>> = HashMap()
            private var isViscidity = false//是否粘性

            constructor(isViscidity: Boolean) : this() {
                this.isViscidity = isViscidity
            }

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

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

            /**
             * 为了防止粘性消息   所以此处用hook处理   分发机制  需要对源码有详细的了解
             */
            fun hook(observer: Observer<T>) {
                val classLiveData: Class<LiveData<*>> = LiveData::class.java
                //反射获取  LiveData中的 SafeIterableMap<Observer<T>, ObserverWrapper> mObservers
                val fieldObservers = classLiveData.getDeclaredField("mObservers")
                fieldObservers.isAccessible = true
                val objectObservers = fieldObservers.get(this)
                val classObservers = objectObservers.javaClass
                //反射获取  SafeIterableMap中的get方法
                val methodGet = classObservers.getDeclaredMethod("get", Any::class.java)
                methodGet.isAccessible = true
                //执行get方法
                val objectWrapperEntry = methodGet.invoke(objectObservers, observer)
                var objectWrapper: Any? = null

                if (objectWrapperEntry is Map.Entry<*, *>) {
                    objectWrapper = (objectWrapperEntry as Map.Entry<*, *>).value
                }
                if (objectWrapper == null) {
                    throw NullPointerException("Wrapper can not be bull!")
                }

                val classObserverWrapper = objectWrapper.javaClass.superclass
                val fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion")
                fieldLastVersion.isAccessible = true
                //get livedata's version
                val fieldVersion = classLiveData.getDeclaredField("mVersion")
                fieldVersion.isAccessible = true
                val objectVersion = fieldVersion.get(this)
                //set wrapper's version
                fieldLastVersion.set(objectWrapper, objectVersion)
            }

        }
    }
}

发送信息

LiveDataBus.get().with(LiveDataBus.KEY_GOTO_HOME, UpdateGotoViewEvent::class.java).value = UpdateGotoViewEvent(0,0)

接收信息

 LiveDataBus.Companion.get().with(LiveDataBus.Companion.getKEY_GOTO_HOME(), UpdateGotoViewEvent.class)
                .observe(this, event -> {
                    if (event != null) {
                        ...
                    }
                });
UpdateGotoViewEvent类代码
/**
 * Created by lahm
 * 跳转界面
 * *@param oneIndex 1级下标
 * *@param twoIndex 2级下标
 */

class UpdateGotoViewEvent(var oneIndex: Int, var twoIndex: Int)

如果是发送简单的类型比如Boolean

直接替换就好

LiveDataBus.get().with(LiveDataBus.KEY_DOWNLOAD_FINISH, Boolean::class.java).value = true
LiveDataBus.get().with(LiveDataBus.KEY_DOWNLOAD_FINISH, Boolean::class.java)
        .observe(this, Observer {
            if (it!!) {
               ...
            }
        })

导包

import android.arch.lifecycle.Observer

粘性:先发送消息再订阅,还是能接收到消息

非粘性:先订阅再发送消息,才能接收到

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值