EventBus,RxBus,LiveDataBus對比分析

三者最大的作用都是對一個Android事件發布/訂閱框架,通過解耦發布者和訂閱者簡化Android事件傳遞。

一、Eventbus

EventBus可以代替Android傳統的Intent、Handler、Broadcast或接口回調,在Fragment、Activity、Service線程之間傳遞數據,執行方法。EventBus最大的特點就是簡潔、解耦。在沒有EventBus之前我們通常用廣播來實現監聽,或者自定義接口函數回調,有的場景我們也可以直接用Intent攜帶簡單數據,或者在線程之間通過Handler處理消息傳遞。但無論是廣播還是Handler機制遠遠不能滿足我們高效的開發。EventBus簡化了應用程序內各組件間、組件與后臺線程間的通信。EventBus一經推出,便受到廣大開發者的推崇。EventBus給Android開發者世界帶來了一種新的框架和思想,就是消息的發布和訂閱。這種思想在其后很多框架中都得到了應用。


image.png

發布/訂閱模式

訂閱發布模式定義了一種“一對多”的依賴關系,讓多個訂閱者對象同時監聽某一個主題對象。這個主題對象在自身狀態變化時,會通知所有訂閱者對象,使它們能夠自動更新自己的狀態。


image.png

使用起來很簡單:

image.png

存在的問題:
① 需要引入兩個包,增加APK體積

image.png

此外,包的內部還依賴了以下幾個庫,造成更多的包大小以及與項目中存在某些包的版本沖突:
image.png

②每次都要注冊和反注冊,寫法繁瑣存在內存泄漏風險。

二、RxBus的出現

RxBus不是一個庫,而是一個文件,實現只有短短30行代碼。RxBus本身不需要過多分析,它的強大完全來自于它基于的RxJava技術。響應式編程(Reactive Programming)技術這幾年特別火,RxJava是它在Java上的實作。RxJava天生就是發布/訂閱模式,而且很容易處理線程切換。所以,RxBus憑借區區30行代碼,就敢挑戰EventBus“江湖老大”的地位。

RxBus原理

在RxJava中有個Subject類,它繼承Observable類,同時實現了Observer接口,因此Subject可以同時擔當訂閱者和被訂閱者的角色,我們使用Subject的子類PublishSubject來創建一個Subject對象(PublishSubject只有被訂閱后才會把接收到的事件立刻發送給訂閱者),在需要接收事件的地方,訂閱該Subject對象,之后如果Subject對象接收到事件,則會發射給該訂閱者,此時Subject對象充當被訂閱者的角色。完成了訂閱,在需要發送事件的地方將事件發送給之前被訂閱的Subject對象,則此時Subject對象作為訂閱者接收事件,然后會立刻將事件轉發給訂閱該Subject對象的訂閱者,以便訂閱者處理相應事件,到這里就完成了事件的發送與處理。

RxBus有很多實現,如:

AndroidKnife/RxBus(https://github.com/AndroidKnife/RxBus) Blankj/RxBus(https://github.com/Blankj/RxBus

由于MDD項目已經使用了RxJava2所以需要引入的包已經現有,很好地利用了,其實正如前面所說的,RxBus的原理是如此簡單,我們項目中自己實現的RxBus:


image.png

發送事件:


image.png

很簡單的一個自定義RxBus類和使用,但是存在兩個問題:

① 項目存在一個頁面訂閱多個事件(如AppHomeActivity目前訂閱四個事件總線,需要重復代碼RxBus.getInstance().toObservable… 四遍太臃腫,可讀性差)
② 使用RxJava發布一個訂閱后,當頁面被finish,此時訂閱邏輯還未完成,如果沒有及時取消訂閱,就會導致Activity/Fragment無法被回收,從而引發內存泄漏。

針對①封裝了一層通用bean,采用switch判斷統一處理:


image.png

image.png
對比舊的eventbus:
image.png
image.png

針對②,其實項目中的retrofit中已經碰到此類問題,只需使用一個CompositeDisposable存儲當前所有的訂閱,然后再onDestroy()中將其dispose()。


image.png

image.png
三、LiveEventBus

從LiveData談起

LiveData是Android Architecture Components提出的框架。LiveData是一個可以被觀察的數據持有類,它可以感知并遵循Activity、Fragment或Service等組件的生命周期。正是由于LiveData對組件生命周期可感知特點,因此可以做到僅在組件處于生命周期的激活狀態時才更新UI數據。LiveData需要一個觀察者對象,一般是Observer類的具體實現。當觀察者的生命周期處于STARTED或RESUMED狀態時,LiveData會通知觀察者數據變化;在觀察者處于其他狀態時,即使LiveData的數據變化了,也不會通知。

LiveDataBus原理圖

image.png

LiveData的優點

image.png

LiveDataBus的實現

image.png

image.png
image.png

image.png
image.png

image.png

image.png
image.png
image.png

LiveEventBus****使用:

在工程中引用

implementation 'com.jeremyliao:live-event-bus:1.5.7'

配置

在Application.onCreate方法中配置:

LiveEventBus
        .config() ...

supportBroadcast 配置支持跨進程、跨APP通信
lifecycleObserverAlwaysActive 配置LifecycleObserver(如Activity)接收消息的模式(默認值true)
autoClear 配置在沒有Observer關聯的時候是否自動清除LiveEvent以釋放內存(默認值false)

使用方法

以生命周期感知模式訂閱消息(根據THIS綁定生命周期)
LiveEventBus
    .get("key_name", String.class)
    .observe(this, new Observer<String>() {
        @Override
        public void onChanged(@Nullable String s) {
        }
    });
發送消息
  • post
    發送一個消息,支持前臺線程、后臺線程發送
LiveEventBus
    .get("key_name")
    .post(value);

存在的問題:

① 需要引入liveeventbus包占用體積,內部更是引入了多個jar包。

image.png

② 為了自動感應生命周期引入lifecycle庫,同時為了支持跨進程、跨APP通信、AndroidX等增加很多類,目前MDD根本用不到,有點事倍功半。

總結

通過3種事件總線引入代價和收益對比分析以及MDD項目對其使用較少和程度較淺,最終選擇Rxbus方式。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容