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,进行版本对齐

相关推荐
gxgldyh8 分钟前
Android Framework源码解析(七):BootAnimation 启动流程解析——开机动画是如何显示出来的?
android
达达尼昂28 分钟前
在 Claude Cowork 中用好 Claude Fable 5
android·人工智能·后端
sTone873751 小时前
写时复制COW的第一性理解
android·c++·flutter
sTone873751 小时前
Zygote的第一性理解
android
sTone873751 小时前
类RN框架通过Service暴露卡片渲染能力给AI Chat
android·react native
灯火不休1 小时前
Android Studio & Flutter 构建命令完全指南
android
杉氧1 小时前
Ktor 全栈之路 (5):JWT 认证全流程实战 —— 打造安全通信闭环
android·架构·kotlin
️学习的小王2 小时前
Python + MySQL 学生信息管理系统实战教程
android·python·mysql
帅次2 小时前
Android 高级工程师面试:Flutter 路由导航 近1年高频追问 18 题
android·flutter·面试
alexhilton10 小时前
MVI模式的完整历史、误解和现代Android范式
android·kotlin·android jetpack