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

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

EventBus的缺點

EventBus作為一個常用的的事件總線庫,它的確很優(yōu)秀,將消息的傳輸過程簡易化了

然而它有著幾個致命的缺點:

  1. 需要注冊和解除注冊,過程繁瑣
  2. 當(dāng)事件很多的時候追查事件流異常困難
  3. 每個對象只能對應(yīng)一個事件,所以不同事件基本都需要一個事件對象存在

其中第二點是最讓人不能忍的,

針對第二點舉例,比如我們需要post一個名為DownloadInfo的一個對象

EventBus.getDefault().post(downloadInfo);

如果我們需要追查這個對象被發(fā)送到了哪里,那只能根據(jù)這個對象來查找

然后就會發(fā)現(xiàn)如下情況

image

哎,一堆引用,想查對象發(fā)送的地方真是夠嗆.

尤其是看別人代碼的時候,簡直是生無可戀啊

EventLiveData

針對EventBus以上痛點,我是不太想用它了,于是EventLiveData順勢而生.

這是基于LiveData魔改的一個類,用于實現(xiàn)事件發(fā)送.

EventLiveData可以在后臺線程發(fā)送事件,不過接收事件的線程是主線程并且不能切換.

EventLiveData構(gòu)造方法有兩個參數(shù):

  • stickyCount: Int 表示粘性事件發(fā)送次數(shù)和發(fā)送模式
  • activeForever: Boolean 是否一直處于激活狀態(tài)

stickyCount

stickyCount如果大于0則表示粘性事件發(fā)送次數(shù),也就是說通過EventLiveData發(fā)送事件之后注冊的觀察者也能收到事件,不過有次數(shù)限制,當(dāng)次數(shù)消耗完,再之后的注冊的觀察者便不會收到事件了;

stickyCount如果等于EventLiveData.NO_STICKY則表示非粘性事件,只有已經(jīng)注冊的觀察者才能收到;

stickyCount如果等于EventLiveData.STICKY_FOREVER則表示為永久的粘性事件,已注冊的觀察者和將來注冊的觀察者都會收到事件;

stickyCount如果等于EventLiveData.SEND_ONCE則表示此事件只會發(fā)送一次.如果已經(jīng)有觀察者,則事件會發(fā)送給所有現(xiàn)在已注冊的觀察者,之后注冊的觀察者不會收到事件,如果暫時沒有觀察者,那么事件只會發(fā)送給將來第一個注冊的觀察者.

activeForever

常規(guī)的LiveData有個特點,就是在界面不可見的時候是收不到消息的,然而如果拿來做個事件發(fā)送,這樣可能并不合適,有時候我們需要在頁面不可見的時候也能收到事件.

activeForever如果為true則表示不管任何時候都會收到事件,如果為false則表示僅在頁面可見的時候才會收到消息.

當(dāng)然這個屬性對于observeForever是無效的,observeForever無法感知生命周期變化,所以不管任何時候都會收到事件.

EventLiveData的使用

EventLiveData依賴

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

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

除了上述的兩個構(gòu)造參數(shù),其它使用和普通的LiveData并沒有什么區(qū)別.

舉例說我們有一個用戶信息需要更新的事件,我們創(chuàng)建如下對象即可

    val userInfoShouldUpdateEvent = EventLiveData<Boolean>(SEND_ONCE, false)

然后在合適的地方注冊觀察者

    userInfoShouldUpdateEvent.observe(owner) {
        getUserInfo()
    }

當(dāng)我們需要發(fā)送事件的時候只需要調(diào)用

    userInfoShouldUpdateEvent.value = true

或者

    userInfoShouldUpdateEvent.postValue(true)

事件池

我們需要一個單例類用于存放EventLiveData,我將其稱之為事件池,只是為了方便管理和方便訪問,其并無其它功能.

我們可以將所有或者大部分EventLiveData都放在名為EventPool(事件池)的單例類中

object EventPool {

    /**
     * 用戶信息更新事件
     */
    val userInfoUpdateEvent = EventLiveData<Boolean>(STICKY_FOREVER, false)

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

然后在合適的地方注冊和使用

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

如果我們需要增加一個事件則只需要在EventPool中增加一個EventLiveData.

結(jié)語

綜上,通過EventLiveData和事件池,我們便沒有了類似EventBus的3個缺點.

通常來說對于Activity和Fragment我們并不需要解除觀察者的注冊,所以使用起來并不繁瑣;

我們也并不需要根據(jù)事件對象來追查事件流,根據(jù)EventLiveData本身的引用追查即可,這樣追查也變得方便快捷;

不同的事件只需要創(chuàng)建不同名的EventLiveData對象即可,我們不需要對不同事件創(chuàng)建不同的事件對象.

GitHub地址

https://github.com/dqh147258/EventLiveData

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容