IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 基于LiveData实现事件总线 -> 正文阅读

[移动开发]基于LiveData实现事件总线

前言:提及事件总线常常使用org.greenrobot:eventbus框架,而本文通过LiveData即可轻松实现Eventbus。
实现:这里只定义了1个LiveData,通过TAG作事件的区分。
1、定义事件基类

data class BaseEvent<T>(
    val tag: Int,
    val msg: T
)

2、定义事件操作类

object EventBus{
    val onEventLiveData = MutableLiveData<BaseEvent<*>>()

    const val TAG_CONNECT_PRINTER_SUCCESS = 1
}

3、注册事件

EventBus.onEventLiveData.observe(this, Observer {
    if (it.tag == EventBus.TAG_CONNECT_PRINTER_SUCCESS) {
        mViewModel.showMsgToastLiveData.value = "连接打印机成功"
    }
})

4、发送事件

EventBus.onEventLiveData.setValue(BaseEvent(EventBus.TAG_CONNECT_PRINTER_SUCCESS, true))


问题:由于LiveData本身是具有数据粘性的(即页面A、B都注册了同一事件,而在A中更新事件后进入B页面则立即会收到更新事件,然而实际场景我们只关注页面注册事件的更新事件,而之前的不需要)
原因:这是LiveData框架本身的设计原因(即注册时给订阅者和LiveData记录初始版本号,更新LiveData时其版本号加1,当订阅者的版本比LiveData小时则更新,而当有新的注册时,订阅者版本为初始值,LiveData为更新后的值,大于初始值所有就收到更新)
方案:注册的时候给订阅者版本号为LiveData的版本号即可。

/**
 * 非粘性LiveData
 */
class UnPeekMutableLiveData<T> : MutableLiveData<T>() {
    private val START_VERSION = -1
    private val mCurrentVersion = AtomicInteger(START_VERSION)

    override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
        super.observe(owner, createObserverWrapper(observer, mCurrentVersion.get()))
    }

    override fun observeForever(observer: Observer<in T>) {
        super.observeForever(createObserverForeverWrapper(observer, mCurrentVersion.get()))
    }


    fun observeSticky(owner: LifecycleOwner, observer: Observer<T>) {
        super.observe(owner, createObserverWrapper(observer, START_VERSION))
    }


    fun observeStickyForever(observer: Observer<in T>) {
        super.observeForever(createObserverForeverWrapper(observer, START_VERSION))
    }

    override fun setValue(value: T) {
        mCurrentVersion.getAndIncrement()
        super.setValue(value)
    }

    override fun removeObserver(observer: Observer<in T>) {
        if (TextUtils.isEmpty(observer.toString())) {
            super.removeObserver(observer)
        } else {
            super.removeObserver(createObserverWrapper(observer, START_VERSION))
        }
    }

    private fun createObserverForeverWrapper(
        observer: Observer<in T>,
        version: Int
    ): MyObserverWrapper<T> {
        return MyObserverWrapper(observer, mCurrentVersion, version, true)
    }

    private fun createObserverWrapper(
        observer: Observer<in T>,
        version: Int
    ): MyObserverWrapper<T> {
        return MyObserverWrapper(observer, mCurrentVersion, version, false)
    }

    fun clear() {
        super.setValue(null)
    }
}
class MyObserverWrapper<T> constructor(
    private val mObserver: Observer<in T>, private val mLiveDataVersion: AtomicInteger,
    private val mVersion: Int, private val mIsForever: Boolean): Observer<T> {

    override fun onChanged(t: T?) {
        if (mLiveDataVersion.get() > mVersion) {
            mObserver.onChanged(t)
        }
    }

    override fun equals(o: Any?): Boolean {
        if (this === o) {
            return true
        }
        if (o == null || javaClass != o.javaClass) {
            return false
        }
        val that = o as MyObserverWrapper<*>
        return Objects.equals(mObserver, that.mObserver)
    }

    override fun hashCode(): Int {
        return Objects.hash(mObserver)
    }

    override fun toString(): String {
        return if (mIsForever) "IS_FOREVER" else ""
    }
}

只需将EventBus里的MutableLiveData替换为UnPeekMutableLiveData即可

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-29 12:16:33  更:2022-04-29 12:17:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 0:04:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码