基于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即可

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LiveData 是用于在 Android 应用程序中观察数据的一个组件。LiveData 是一个可观察的数据持有者类,它具有生命周期感知能力,因此它会自动管理它与 Activity 和 Fragment 生命周期的关系,从而可以避免内存泄漏和崩溃。 LiveData 的一个重要特性是它可以通知观察者数据已更改。当 LiveData 的值发生更改时,它会自动通知所有观察者。这意味着您无需手动更新 UI 或执行其他操作以反映数据更改。LiveData 还支持数据转换和过滤,因此您可以将原始数据转换为 UI 可以直接使用的格式。 LiveData 使用观察者模式进行数据监听,您可以使用 `observe()` 方法将观察者添加到 LiveData 实例中,该方法需要传入一个 LifecycleOwner 和一个 Observer 对象。LifecycleOwner 表示 LiveData 与哪个组件的生命周期绑定,通常是 Activity 或 Fragment。Observer 对象定义了当 LiveData 的值更改时要执行的操作。 下面是一个简单的示例,演示如何使用 LiveData 监听数据更改: ``` // 创建一个 LiveData 实例 val myLiveData = MutableLiveData<String>() // 将观察者添加到 LiveData 实例中 myLiveData.observe(this, Observer { newValue -> // 在这里更新 UI 或执行其他操作 textView.text = newValue }) // 更改 LiveData 的值 myLiveData.value = "Hello World" ``` 在上面的示例中,我们创建了一个名为 `myLiveData` 的 LiveData 实例,并将其与当前组件的生命周期绑定。我们还将一个 Observer 对象传递给 `observe()` 方法,以便在 LiveData 的值更改时执行操作。当我们调用 `myLiveData.value = "Hello World"` 时,LiveData 会自动通知所有观察者,以便更新 UI 或执行其他操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值