Kotlin版 自定义的LiveDataBus

先上代码:

Kotlin 复制代码
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,进行版本对齐

相关推荐
90后的晨仔13 小时前
Android Studio 项目模板完全指南
android
summerkissyou198713 小时前
Android-SurfaceView-投屏-常见问题
android·surfaceview
明天就是Friday14 小时前
Android实战项目④ OkHttp WebSocket开发即时通讯App 完整源码详解
android·websocket·okhttp
吉哥机顶盒刷机15 小时前
好物分享:DNA-Android-4.0.5安卓固件解包、打包工具
android·好物分享
三棱球15 小时前
App逆向学习笔记(三)——Android开发入门课
android·笔记
安卓机器16 小时前
rom定制系列------魅族16x 解锁bl root与Flyme9安卓10线刷固件 传感器修复
android·魅族16x玩机
wellc18 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
CYY9518 小时前
Android 打印 SO 库的异常日志
android
找藉口是失败者的习惯20 小时前
深入理解 Android 无障碍服务
android