EventBus替换方案--EventLiveData和事件池

EventBus替换方案--EventLiveData和事件池

EventBus的缺点

EventBus作为一个常用的的事件总线库,它的确很优秀,将消息的传输过程简易化了

然而它有着几个致命的缺点:

  1. 需要注册和解除注册,过程繁琐
  2. 当事件很多的时候追查事件流异常困难
  3. 每个对象只能对应一个事件,所以不同事件基本都需要一个事件对象存在

其中第二点是最让人不能忍的,

针对第二点举例,比如我们需要post一个名为DownloadInfo的一个对象

EventBus.getDefault().post(downloadInfo);

如果我们需要追查这个对象被发送到了哪里,那只能根据这个对象来查找

然后就会发现如下情况

image

哎,一堆引用,想查对象发送的地方真是够呛.

尤其是看别人代码的时候,简直是生无可恋啊

EventLiveData

针对EventBus以上痛点,我是不太想用它了,于是EventLiveData顺势而生.

这是基于LiveData魔改的一个类,用于实现事件发送.

EventLiveData可以在后台线程发送事件,不过接收事件的线程是主线程并且不能切换.

EventLiveData构造方法有两个参数:

  • stickyCount: Int 表示粘性事件发送次数和发送模式
  • activeForever: Boolean 是否一直处于激活状态

stickyCount

stickyCount如果大于0则表示粘性事件发送次数,也就是说通过EventLiveData发送事件之后注册的观察者也能收到事件,不过有次数限制,当次数消耗完,再之后的注册的观察者便不会收到事件了;

stickyCount如果等于EventLiveData.NO_STICKY则表示非粘性事件,只有已经注册的观察者才能收到;

stickyCount如果等于EventLiveData.STICKY_FOREVER则表示为永久的粘性事件,已注册的观察者和将来注册的观察者都会收到事件;

stickyCount如果等于EventLiveData.SEND_ONCE则表示此事件只会发送一次.如果已经有观察者,则事件会发送给所有现在已注册的观察者,之后注册的观察者不会收到事件,如果暂时没有观察者,那么事件只会发送给将来第一个注册的观察者.

activeForever

常规的LiveData有个特点,就是在界面不可见的时候是收不到消息的,然而如果拿来做个事件发送,这样可能并不合适,有时候我们需要在页面不可见的时候也能收到事件.

activeForever如果为true则表示不管任何时候都会收到事件,如果为false则表示仅在页面可见的时候才会收到消息.

当然这个属性对于observeForever是无效的,observeForever无法感知生命周期变化,所以不管任何时候都会收到事件.

EventLiveData的使用

EventLiveData依赖

    allprojects {
        repositories {
            //...
            maven { url 'https://www.jitpack.io' }
        }
    }

    dependencies {
            implementation 'com.github.dqh147258:EventLiveData:1.0.+'
    }

除了上述的两个构造参数,其它使用和普通的LiveData并没有什么区别.

举例说我们有一个用户信息需要更新的事件,我们创建如下对象即可

    val userInfoShouldUpdateEvent = EventLiveData(SEND_ONCE, false)

然后在合适的地方注册观察者

    userInfoShouldUpdateEvent.observe(owner) {
        getUserInfo()
    }

当我们需要发送事件的时候只需要调用

    userInfoShouldUpdateEvent.value = true

或者

    userInfoShouldUpdateEvent.postValue(true)

事件池

我们需要一个单例类用于存放EventLiveData,我将其称之为事件池,只是为了方便管理和方便访问,其并无其它功能.

我们可以将所有或者大部分EventLiveData都放在名为EventPool(事件池)的单例类中

object EventPool {

    /**
     * 用户信息更新事件
     */
    val userInfoUpdateEvent = EventLiveData(STICKY_FOREVER, false)

    /**
     *  用户信息需要更新事件
     */
    val userInfoShouldUpdateEvent = EventLiveData(SEND_ONCE, false)
    
    //......
}

然后在合适的地方注册和使用

    EventPool.userInfoShouldUpdateEvent.observe(owner) {
        getUserInfo()
    }
    EventPool.userInfoShouldUpdateEvent.value = true

如果我们需要增加一个事件则只需要在EventPool中增加一个EventLiveData.

结语

综上,通过EventLiveData和事件池,我们便没有了类似EventBus的3个缺点.

通常来说对于Activity和Fragment我们并不需要解除观察者的注册,所以使用起来并不繁琐;

我们也并不需要根据事件对象来追查事件流,根据EventLiveData本身的引用追查即可,这样追查也变得方便快捷;

不同的事件只需要创建不同名的EventLiveData对象即可,我们不需要对不同事件创建不同的事件对象.

GitHub地址

https://github.com/dqh147258/EventLiveData

你可能感兴趣的:(EventBus替换方案--EventLiveData和事件池)