Kotlin版 自定义的LiveDataBus

先上代码:

object LiveDataBusKT {

    //    private val bus: MutableMap<String, BusMutableLiveData<Any>> by lazy { HashMap() }
    private val MAX_BUS_COUNT = 100 // 最大允许的 bus 对象数量
    private val bus: LruCache<String, BusMutableLiveData<Any>> = LruCache(MAX_BUS_COUNT)
    //暴露一个线程安全的,给外界注册,订阅者关系
    @Synchronized
    fun <T>with(key:String,type:Class<T>,isStick: Boolean =true):BusMutableLiveData<T>{
        var liveData = bus.get(key)
        if (liveData == null) {
            liveData = BusMutableLiveData(isStick)
            bus.put(key, liveData)
        }
//        if (!bus.containsKey(key)){
//            bus[key] = BusMutableLiveData(isStick)
//        }
        return bus[key] as BusMutableLiveData<T>
    }
    class BusMutableLiveData<T> private constructor() :MutableLiveData<T>(){
        var isStick  =false //开启,关闭 粘性

        //次构造
        constructor(isStick: Boolean):this(){
            this.isStick =isStick
        }
        //hook
        override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
            super.observe(owner, observer)
            if (!isStick){
                hook(observer =observer)
            }else{
            }

        }

        private fun <T> hook(observer: Observer<in T>) {
            // 获取mLastVersion
            val liveDataClass = LiveData::class.java

            // getDeclaredField是可以获取一个类的所有字段.
            // getField只能获取类的public 字段.
            val mObserversField = liveDataClass.getDeclaredField("mObservers")
            mObserversField.isAccessible = true //private 修饰也可以访问
            val mObserversObject = mObserversField.get(this)

            // 获取 private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
            val mObserversClass = mObserversObject.javaClass

            // 获取 mObservers 的 get方法   protected Entry<K, V> get(K k){}
            val get = mObserversClass.getDeclaredMethod("get", Any::class.java)
            get.isAccessible = true

            // 执行get方法
            val invoke = get.invoke(mObserversObject, observer)

            // 获取 entry 中 的 value
            var observerWrapper: Any? = null
            if (invoke != null && invoke is Map.Entry<*, *>) {
                observerWrapper = invoke.value
            }

            if (observerWrapper == null) {
                throw NullPointerException("observerWrapper is null")
            }

            // 得到observerWrapper的类对象
            val superclass = observerWrapper.javaClass.superclass
            val mLastVersionField = superclass.getDeclaredField("mLastVersion")
            mLastVersionField.isAccessible = true

            // 得到mVersion
            val mVersionField = liveDataClass.getDeclaredField("mVersion")
            mVersionField.isAccessible = true

            // 版本对齐
            val versionValue = mVersionField.get(this)
            mLastVersionField.set(observerWrapper, versionValue)
        }

    }
}

为了开启,关闭粘性事件,使用了 isStick 控制。

通过继承 MutableLiveData,在observe的时候hook 获取 mLastVersion 和mVersion,进行版本对齐

相关推荐

  1. Kotlin 定义LiveDataBus

    2023-12-29 07:14:01       50 阅读
  2. Kotlin定义Json反序列化

    2023-12-29 07:14:01       54 阅读
  3. Kotlin语法入门-定义注解(7)

    2023-12-29 07:14:01       31 阅读
  4. 定义函数使用

    2023-12-29 07:14:01       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-29 07:14:01       91 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-29 07:14:01       97 阅读
  3. 在Django里面运行非项目文件

    2023-12-29 07:14:01       78 阅读
  4. Python语言-面向对象

    2023-12-29 07:14:01       88 阅读

热门阅读

  1. 构造哈夫曼树(数据结构实训)(难度系数85)

    2023-12-29 07:14:01       56 阅读
  2. 【浏览器】Web存储梳理和总结

    2023-12-29 07:14:01       48 阅读
  3. 《C#程序设计教程》总复习

    2023-12-29 07:14:01       50 阅读
  4. Vue2面试题:说一下v-show、v-if、v-for的理解?

    2023-12-29 07:14:01       52 阅读
  5. Latex如何转成Word

    2023-12-29 07:14:01       55 阅读
  6. stm32采用队列方式接收和发送RS485串口数据

    2023-12-29 07:14:01       49 阅读
  7. 第41节: Vue3 watch函数

    2023-12-29 07:14:01       61 阅读
  8. uniapp 目录结构

    2023-12-29 07:14:01       53 阅读
  9. K8S Ingress-Nginx导出TCP端口

    2023-12-29 07:14:01       58 阅读