Kotlin版 自定义的LiveDataBus

这篇具有很好参考价值的文章主要介绍了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,进行版本对齐文章来源地址https://www.toymoban.com/news/detail-772926.html

到了这里,关于Kotlin版 自定义的LiveDataBus的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Kotlin-变量定义,与类型

    Kotlin可以定义的时候不标明数据的数据类型,编译器会根据初始值确定类型 提供4种类型:Byte、Short、Int、Long 但是Kotlin时安全语言,所以不允许为空,如果需要存储空值的话就需要使用Byte?、Short?、Int?、Long?。 普通类型的整数类型会映射到java的基本类型;带?的数据类

    2024年01月16日
    浏览(39)
  • kotlin怎么定义类

    在Kotlin中,你可以使用class来定义一个类。以下是一个简单的例子: 这个例子定义了一个名为MyClass的类。你可以在类体中定义属性和方法。 如果你想定义一个带有属性的类,你可以这样做: 在这个例子中,我们定义了一个名为Person的类,它有两个属性:name和age。na

    2024年02月10日
    浏览(26)
  • Kotlin语法入门-自定义注解(7)

    示例: 注解的附加属性可以通过用元注解标注注解类来指定: @Target 指定可以用该注解标注的元素的可能的类型(类、函数、属性与表达式); @Retention 指定该注解是否存储在编译后的 class 文件中,以及它在运行时能否通过反射可见 (默认都是 true); @Repeatable 允许在单个

    2024年04月25日
    浏览(29)
  • Android---Kotlin 学习009

    在 java 里如果一个类没有被 final 修饰,那么它都是可以被继承的。而在 kotlin 中,类默认都是封闭的,要让某个类开放继承,必须使用 open 修饰它,否则会编译报错。此外在子类中,如果要复写父类的某个方法,需要用到 Override (在 kt 中就不是注解了)

    2024年02月01日
    浏览(45)
  • Android Kotlin 协程初探

    维基百科:协程,英文Coroutine [kəru’tin] (可入厅),是计算机程序的一类组件,推广了协作式多任务的子程序,允许执行被挂起与被恢复。 作为Google钦定的Android开发首选语言Kotlin,协程并不是 Kotlin 提出来的新概念,目前有协程概念的编程语言有Lua语言、Python语言、Go语言

    2024年02月08日
    浏览(46)
  • Android开发中,JDK版本,Gradle版本,Kotlin插件与Kotlin版本等各自对应关系

    一、Gradle版本和Java版本对应关系 二、Gradle版本和Kotlin版本对应关系 三、Gradle版本和Gradle插件版本匹配关系 可以在Android Studio的 File Project Structure Project 菜单中指定插件版本,也可以在顶级 build.gradle 文件中进行修改

    2024年03月15日
    浏览(68)
  • Kotlin 轻量级Android开发

    Kotlin 是一门运行在 JVM 之上的语言。 它由 Jetbrains 创建,而 Jetbrains 则是诸多强大的工具(如知名的 Java IDE IntelliJ IDEA )背后的公司。 Kotlin 是一门非常简单的语言,其主要目标之一就是提供强大语言的同时又保持简单且精简的语法。 其主要特性如下所示: 轻量级:这一点对

    2024年02月07日
    浏览(161)
  • Android Glide CustomTarget ,kotlin

    Android Glide CustomTarget ,kotlin       android Glide CustomViewTarget,java_zhangphil的博客-CSDN博客 【代码】android Glide CustomViewTarget,java。 https://blog.csdn.net/zhangphil/article/details/129493334 Android Glide预加载preload ,kotlin_zhangphil的博客-CSDN博客 【代码】Android Paging 3,kotlin(1)在实际的开发中,虽然G

    2024年02月16日
    浏览(45)
  • Android AlertDialog setView,kotlin

    Android AlertDialog setView,kotlin             Android DialogFragment(1)_zhangphil的博客-CSDN博客 Android DialogFragment(1)和过去的AlertDialog类似,Android引入的DialogFragment旨在为开发者提供一个“富”dialog,而不必受到过去Android AlertDialog的局限。首先,DialogFragment是一个Fragment,它有Fragm

    2024年02月13日
    浏览(59)
  • Android-实现一个登录页面(kotlin)

    首先,确保你已经安装了 Android Studio。如果还没有安装,请访问 Android Studio 官网 下载并安装。 - 安装并配置好 Android Studio gradle-wrapper.properties build.gradle(:Project) setting.gradle - 对 Kotlin 语言有基本了解 首先,打开 Android Studio 并创建一个新项目。选择 \\\"Empty Activity\\\" 模板,然后为项

    2023年04月25日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包