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

發(fā)布/訂閱模式
訂閱發(fā)布模式定義了一種“一對多”的依賴關(guān)系,讓多個(gè)訂閱者對象同時(shí)監(jiān)聽某一個(gè)主題對象。這個(gè)主題對象在自身狀態(tài)變化時(shí),會通知所有訂閱者對象,使它們能夠自動更新自己的狀態(tài)。

使用起來很簡單:

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

此外,包的內(nèi)部還依賴了以下幾個(gè)庫,造成更多的包大小以及與項(xiàng)目中存在某些包的版本沖突:

②每次都要注冊和反注冊,寫法繁瑣存在內(nèi)存泄漏風(fēng)險(xiǎn)。
二、RxBus的出現(xiàn)
RxBus不是一個(gè)庫,而是一個(gè)文件,實(shí)現(xiàn)只有短短30行代碼。RxBus本身不需要過多分析,它的強(qiáng)大完全來自于它基于的RxJava技術(shù)。響應(yīng)式編程(Reactive Programming)技術(shù)這幾年特別火,RxJava是它在Java上的實(shí)作。RxJava天生就是發(fā)布/訂閱模式,而且很容易處理線程切換。所以,RxBus憑借區(qū)區(qū)30行代碼,就敢挑戰(zhàn)EventBus“江湖老大”的地位。
RxBus原理
在RxJava中有個(gè)Subject類,它繼承Observable類,同時(shí)實(shí)現(xiàn)了Observer接口,因此Subject可以同時(shí)擔(dān)當(dāng)訂閱者和被訂閱者的角色,我們使用Subject的子類PublishSubject來創(chuàng)建一個(gè)Subject對象(PublishSubject只有被訂閱后才會把接收到的事件立刻發(fā)送給訂閱者),在需要接收事件的地方,訂閱該Subject對象,之后如果Subject對象接收到事件,則會發(fā)射給該訂閱者,此時(shí)Subject對象充當(dāng)被訂閱者的角色。完成了訂閱,在需要發(fā)送事件的地方將事件發(fā)送給之前被訂閱的Subject對象,則此時(shí)Subject對象作為訂閱者接收事件,然后會立刻將事件轉(zhuǎn)發(fā)給訂閱該Subject對象的訂閱者,以便訂閱者處理相應(yīng)事件,到這里就完成了事件的發(fā)送與處理。
RxBus有很多實(shí)現(xiàn),如:
AndroidKnife/RxBus(https://github.com/AndroidKnife/RxBus) Blankj/RxBus(https://github.com/Blankj/RxBus)
由于MDD項(xiàng)目已經(jīng)使用了RxJava2所以需要引入的包已經(jīng)現(xiàn)有,很好地利用了,其實(shí)正如前面所說的,RxBus的原理是如此簡單,我們項(xiàng)目中自己實(shí)現(xiàn)的RxBus:

發(fā)送事件:

很簡單的一個(gè)自定義RxBus類和使用,但是存在兩個(gè)問題:
① 項(xiàng)目存在一個(gè)頁面訂閱多個(gè)事件(如AppHomeActivity目前訂閱四個(gè)事件總線,需要重復(fù)代碼RxBus.getInstance().toObservable… 四遍太臃腫,可讀性差)
② 使用RxJava發(fā)布一個(gè)訂閱后,當(dāng)頁面被finish,此時(shí)訂閱邏輯還未完成,如果沒有及時(shí)取消訂閱,就會導(dǎo)致Activity/Fragment無法被回收,從而引發(fā)內(nèi)存泄漏。
針對①封裝了一層通用bean,采用switch判斷統(tǒng)一處理:


對比舊的eventbus:


針對②,其實(shí)項(xiàng)目中的retrofit中已經(jīng)碰到此類問題,只需使用一個(gè)CompositeDisposable存儲當(dāng)前所有的訂閱,然后再onDestroy()中將其dispose()。


三、LiveEventBus
從LiveData談起
LiveData是Android Architecture Components提出的框架。LiveData是一個(gè)可以被觀察的數(shù)據(jù)持有類,它可以感知并遵循Activity、Fragment或Service等組件的生命周期。正是由于LiveData對組件生命周期可感知特點(diǎn),因此可以做到僅在組件處于生命周期的激活狀態(tài)時(shí)才更新UI數(shù)據(jù)。LiveData需要一個(gè)觀察者對象,一般是Observer類的具體實(shí)現(xiàn)。當(dāng)觀察者的生命周期處于STARTED或RESUMED狀態(tài)時(shí),LiveData會通知觀察者數(shù)據(jù)變化;在觀察者處于其他狀態(tài)時(shí),即使LiveData的數(shù)據(jù)變化了,也不會通知。
LiveDataBus原理圖

LiveData的優(yōu)點(diǎn)

LiveDataBus的實(shí)現(xiàn)









LiveEventBus****使用:
在工程中引用
implementation 'com.jeremyliao:live-event-bus:1.5.7'
配置
在Application.onCreate方法中配置:
LiveEventBus
.config() ...
supportBroadcast 配置支持跨進(jìn)程、跨APP通信
lifecycleObserverAlwaysActive 配置LifecycleObserver(如Activity)接收消息的模式(默認(rèn)值true)
autoClear 配置在沒有Observer關(guān)聯(lián)的時(shí)候是否自動清除LiveEvent以釋放內(nèi)存(默認(rèn)值false)
使用方法
以生命周期感知模式訂閱消息(根據(jù)THIS綁定生命周期)
LiveEventBus
.get("key_name", String.class)
.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
}
});
發(fā)送消息
-
post
發(fā)送一個(gè)消息,支持前臺線程、后臺線程發(fā)送
LiveEventBus
.get("key_name")
.post(value);
存在的問題:
① 需要引入liveeventbus包占用體積,內(nèi)部更是引入了多個(gè)jar包。

② 為了自動感應(yīng)生命周期引入lifecycle庫,同時(shí)為了支持跨進(jìn)程、跨APP通信、AndroidX等增加很多類,目前MDD根本用不到,有點(diǎn)事倍功半。
總結(jié)
通過3種事件總線引入代價(jià)和收益對比分析以及MDD項(xiàng)目對其使用較少和程度較淺,最終選擇Rxbus方式。