三者最大的作用都是對一個Android事件發布/訂閱框架,通過解耦發布者和訂閱者簡化Android事件傳遞。
一、Eventbus
EventBus可以代替Android傳統的Intent、Handler、Broadcast或接口回調,在Fragment、Activity、Service線程之間傳遞數據,執行方法。EventBus最大的特點就是簡潔、解耦。在沒有EventBus之前我們通常用廣播來實現監聽,或者自定義接口函數回調,有的場景我們也可以直接用Intent攜帶簡單數據,或者在線程之間通過Handler處理消息傳遞。但無論是廣播還是Handler機制遠遠不能滿足我們高效的開發。EventBus簡化了應用程序內各組件間、組件與后臺線程間的通信。EventBus一經推出,便受到廣大開發者的推崇。EventBus給Android開發者世界帶來了一種新的框架和思想,就是消息的發布和訂閱。這種思想在其后很多框架中都得到了應用。
發布/訂閱模式
訂閱發布模式定義了一種“一對多”的依賴關系,讓多個訂閱者對象同時監聽某一個主題對象。這個主題對象在自身狀態變化時,會通知所有訂閱者對象,使它們能夠自動更新自己的狀態。
使用起來很簡單:
存在的問題:
① 需要引入兩個包,增加APK體積
此外,包的內部還依賴了以下幾個庫,造成更多的包大小以及與項目中存在某些包的版本沖突:
②每次都要注冊和反注冊,寫法繁瑣存在內存泄漏風險。
二、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:
發送事件:
很簡單的一個自定義RxBus類和使用,但是存在兩個問題:
① 項目存在一個頁面訂閱多個事件(如AppHomeActivity目前訂閱四個事件總線,需要重復代碼RxBus.getInstance().toObservable… 四遍太臃腫,可讀性差)
② 使用RxJava發布一個訂閱后,當頁面被finish,此時訂閱邏輯還未完成,如果沒有及時取消訂閱,就會導致Activity/Fragment無法被回收,從而引發內存泄漏。
針對①封裝了一層通用bean,采用switch判斷統一處理:
對比舊的eventbus:
針對②,其實項目中的retrofit中已經碰到此類問題,只需使用一個CompositeDisposable存儲當前所有的訂閱,然后再onDestroy()中將其dispose()。
三、LiveEventBus
從LiveData談起
LiveData是Android Architecture Components提出的框架。LiveData是一個可以被觀察的數據持有類,它可以感知并遵循Activity、Fragment或Service等組件的生命周期。正是由于LiveData對組件生命周期可感知特點,因此可以做到僅在組件處于生命周期的激活狀態時才更新UI數據。LiveData需要一個觀察者對象,一般是Observer類的具體實現。當觀察者的生命周期處于STARTED或RESUMED狀態時,LiveData會通知觀察者數據變化;在觀察者處于其他狀態時,即使LiveData的數據變化了,也不會通知。
LiveDataBus原理圖
LiveData的優點
LiveDataBus的實現
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包。
② 為了自動感應生命周期引入lifecycle庫,同時為了支持跨進程、跨APP通信、AndroidX等增加很多類,目前MDD根本用不到,有點事倍功半。
總結
通過3種事件總線引入代價和收益對比分析以及MDD項目對其使用較少和程度較淺,最終選擇Rxbus方式。