LiveDataBus
項(xiàng)目開(kāi)發(fā)中所能使用到的組建通信方式亏栈?
Intent
Handler
Broadcast
Interface
AIDL
已有的組建通信框架:
Rxjava
優(yōu)點(diǎn):效率高绒北,無(wú)內(nèi)存泄漏镇饮,具有生命周期
缺點(diǎn):基于Rxjava,學(xué)習(xí)成本太大储藐,而且依賴(lài)的包有2.2M嘶是,會(huì)對(duì)我們的apk產(chǎn)生一定的負(fù)擔(dān)
EventBus
優(yōu)點(diǎn):使用簡(jiǎn)單聂喇,能達(dá)到項(xiàng)目基本需求
缺點(diǎn):混淆問(wèn)題蔚携,無(wú)法感知生命周期酝蜒,很難追蹤到發(fā)布者
LiveDataBus
使用簡(jiǎn)單
代碼量少
官方提供了很穩(wěn)定的并且會(huì)一直維護(hù)的可依賴(lài)包
能感知組件的生命周期
不會(huì)存在內(nèi)存泄漏
Android框架組件之Lifecycle:?
? ? 具有生命感知的亡脑,不但能夠監(jiān)聽(tīng)Activity霉咨、Fragment的生命周期途戒,還能夠回調(diào)相應(yīng)的方法僵驰,同時(shí)他能夠?qū)崟r(shí)的獲取當(dāng)前Activity、Fragment的狀態(tài)
LiveData
是一個(gè)數(shù)據(jù)持有類(lèi)打月,持有數(shù)據(jù)并且這個(gè)數(shù)據(jù)能被觀察者監(jiān)聽(tīng),而且它是和lifecycle綁定的,具有生命周期感知的,解決內(nèi)存泄漏和引用問(wèn)題猪瞬。
Hook
? ? 可以用在事件傳送的過(guò)程中截獲并監(jiān)聽(tīng)事件的傳輸陈瘦,將自身的代碼與系統(tǒng)方法進(jìn)行融入痊项。這樣,當(dāng)這些方法被調(diào)用時(shí)皱埠,也就可以執(zhí)行我們自己的代碼边器,這也就是面向?qū)ο蟮木幊趟枷耄ˋOP)
其實(shí)就是通過(guò)反射獲取到Hook點(diǎn),然后在Hook點(diǎn)執(zhí)行我們要插入的方法或者改變?cè)镜倪壿嫷膮?shù)恒界,然后再接著執(zhí)行它原本要執(zhí)行的邏輯仗处。
以下內(nèi)容來(lái)源于
https://www.cnblogs.com/meituantech/p/9376449.html
發(fā)布/訂閱模式
訂閱發(fā)布模式定義了一種“一對(duì)多”的依賴(lài)關(guān)系,讓多個(gè)訂閱者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象吃环。這個(gè)主題對(duì)象在自身狀態(tài)變化時(shí)郁轻,會(huì)通知所有訂閱者對(duì)象,使它們能夠自動(dòng)更新自己的狀態(tài)竭沫。
從EventBus說(shuō)起
EventBus是一個(gè)Android事件發(fā)布/訂閱框架蜕提,通過(guò)解耦發(fā)布者和訂閱者簡(jiǎn)化Android事件傳遞谎势。EventBus可以代替Android傳統(tǒng)的Intent脏榆、Handler台谍、Broadcast或接口回調(diào)趁蕊,在Fragment介衔、Activity、Service線(xiàn)程之間傳遞數(shù)據(jù)赃泡,執(zhí)行方法俄烁。
EventBus最大的特點(diǎn)就是簡(jiǎn)潔级野、解耦蓖柔。在沒(méi)有EventBus之前我們通常用廣播來(lái)實(shí)現(xiàn)監(jiān)聽(tīng),或者自定義接口函數(shù)回調(diào)牢贸,有的場(chǎng)景我們也可以直接用Intent攜帶簡(jiǎn)單數(shù)據(jù)潜索,或者在線(xiàn)程之間通過(guò)Handler處理消息傳遞竹习。但無(wú)論是廣播還是Handler機(jī)制遠(yuǎn)遠(yuǎn)不能滿(mǎn)足我們高效的開(kāi)發(fā)列牺。EventBus簡(jiǎn)化了應(yīng)用程序內(nèi)各組件間昔园、組件與后臺(tái)線(xiàn)程間的通信默刚。EventBus一經(jīng)推出,便受到廣大開(kāi)發(fā)者的推崇澜搅。
現(xiàn)在看來(lái)勉躺,EventBus給Android開(kāi)發(fā)者世界帶來(lái)了一種新的框架和思想饵溅,就是消息的發(fā)布和訂閱妇萄。這種思想在其后很多框架中都得到了應(yīng)用。
RxBus的出現(xiàn)
RxBus不是一個(gè)庫(kù)唇牧,而是一個(gè)文件丐重,實(shí)現(xiàn)只有短短30行代碼扮惦。RxBus本身不需要過(guò)多分析,它的強(qiáng)大完全來(lái)自于它基于的RxJava技術(shù)。響應(yīng)式編程(Reactive Programming)技術(shù)這幾年特別火纳猪,RxJava是它在Java上的實(shí)作桃笙。RxJava天生就是發(fā)布/訂閱模式搏明,而且很容易處理線(xiàn)程切換星著。所以,RxBus憑借區(qū)區(qū)30行代碼虚循,就敢挑戰(zhàn)EventBus“江湖老大”的地位横缔。
RxBus原理
在RxJava中有個(gè)Subject類(lèi)茎刚,它繼承Observable類(lèi),同時(shí)實(shí)現(xiàn)了Observer接口粮坞,因此Subject可以同時(shí)擔(dān)當(dāng)訂閱者和被訂閱者的角色,我們使用Subject的子類(lèi)PublishSubject來(lái)創(chuàng)建一個(gè)Subject對(duì)象(PublishSubject只有被訂閱后才會(huì)把接收到的事件立刻發(fā)送給訂閱者)妇押,在需要接收事件的地方敲霍,訂閱該Subject對(duì)象肩杈,之后如果Subject對(duì)象接收到事件解寝,則會(huì)發(fā)射給該訂閱者聋伦,此時(shí)Subject對(duì)象充當(dāng)被訂閱者的角色。
完成了訂閱兵拢,在需要發(fā)送事件的地方將事件發(fā)送給之前被訂閱的Subject對(duì)象说铃,則此時(shí)Subject對(duì)象作為訂閱者接收事件腻扇,然后會(huì)立刻將事件轉(zhuǎn)發(fā)給訂閱該Subject對(duì)象的訂閱者砾嫉,以便訂閱者處理相應(yīng)事件焰枢,到這里就完成了事件的發(fā)送與處理。
最后就是取消訂閱的操作了暑椰,RxJava中一汽,訂閱操作會(huì)返回一個(gè)Subscription對(duì)象召夹,以便在合適的時(shí)機(jī)取消訂閱,防止內(nèi)存泄漏纱意,如果一個(gè)類(lèi)產(chǎn)生多個(gè)Subscription對(duì)象偷霉,我們可以用一個(gè)CompositeSubscription存儲(chǔ)起來(lái)类少,以進(jìn)行批量的取消訂閱渔扎。
RxBus有很多實(shí)現(xiàn),如:
AndroidKnife/RxBus(https://github.com/AndroidKnife/RxBus)
Blankj/RxBus(https://github.com/Blankj/RxBus)
其實(shí)正如前面所說(shuō)的残吩,RxBus的原理是如此簡(jiǎn)單世剖,我們自己都可以寫(xiě)出一個(gè)RxBus的實(shí)現(xiàn):
基于RxJava1的RxBus實(shí)現(xiàn):
publicfinalclassRxBus{
privatefinalSubject?bus;
privateRxBus(){
bus?=newSerializedSubject<>(PublishSubject.create());
}
privatestaticclassSingletonHolder{
privatestaticfinalRxBus?defaultRxBus?=newRxBus();
}
publicstaticRxBusgetInstance(){
returnSingletonHolder.defaultRxBus;
}
/*
?????*?發(fā)送
?????*/
publicvoidpost(Object?o){
bus.onNext(o);
}
/*
?????*?是否有Observable訂閱
?????*/
publicbooleanhasObservable(){
returnbus.hasObservers();
}
/*
?????*?轉(zhuǎn)換為特定類(lèi)型的Obserbale
?????*/
publicObservable<T>?toObservable(Class<T>?type){
returnbus.ofType(type);
}
}
基于RxJava2的RxBus實(shí)現(xiàn):
publicfinalclassRxBus2{
????private?final?Subject<Object>?bus;
????private?RxBus2()?{
????????//?toSerialized?method?made?bus?thread?safe
????????bus?=?PublishSubject.create().toSerialized();
????}
publicstaticRxBus2getInstance(){
????????return?Holder.BUS;
????}
privatestaticclassHolder{
????????private?static?final?RxBus2?BUS?=?new?RxBus2();
????}
publicvoidpost(Objectobj){
????????bus.onNext(obj);
????}
publicObservabletoObservable(Class?tClass){
????????return?bus.ofType(tClass);
????}
publicObservabletoObservable(){
????????return?bus;
????}
publicbooleanhasObservers(){
????????return?bus.hasObservers();
????}
}
LiveData是Android Architecture Components提出的框架祖凫。LiveData是一個(gè)可以被觀察的數(shù)據(jù)持有類(lèi),它可以感知并遵循Activity遭庶、Fragment或Service等組件的生命周期峦睡。正是由于LiveData對(duì)組件生命周期可感知特點(diǎn)榨了,因此可以做到僅在組件處于生命周期的激活狀態(tài)時(shí)才更新UI數(shù)據(jù)攘蔽。
LiveData需要一個(gè)觀察者對(duì)象满俗,一般是Observer類(lèi)的具體實(shí)現(xiàn)作岖。當(dāng)觀察者的生命周期處于STARTED或RESUMED狀態(tài)時(shí)痘儡,LiveData會(huì)通知觀察者數(shù)據(jù)變化沉删;在觀察者處于其他狀態(tài)時(shí)丑念,即使LiveData的數(shù)據(jù)變化了结蟋,也不會(huì)通知嵌屎。
LiveData的優(yōu)點(diǎn)
UI和實(shí)時(shí)數(shù)據(jù)保持一致宝惰,因?yàn)長(zhǎng)iveData采用的是觀察者模式,這樣一來(lái)就可以在數(shù)據(jù)發(fā)生改變時(shí)獲得通知尊残,更新UI寝衫。
避免內(nèi)存泄漏慰毅,觀察者被綁定到組件的生命周期上扎阶,當(dāng)被綁定的組件銷(xiāo)毀(destroy)時(shí)东臀,觀察者會(huì)立刻自動(dòng)清理自身的數(shù)據(jù)。
不會(huì)再產(chǎn)生由于Activity處于stop狀態(tài)而引起的崩潰贱勃,例如:當(dāng)Activity處于后臺(tái)狀態(tài)時(shí)贵扰,是不會(huì)收到LiveData的任何事件的戚绕。
不需要再解決生命周期帶來(lái)的問(wèn)題,LiveData可以感知被綁定的組件的生命周期耘子,只有在活躍狀態(tài)才會(huì)通知數(shù)據(jù)變化谷誓。
實(shí)時(shí)數(shù)據(jù)刷新捍歪,當(dāng)組件處于活躍狀態(tài)或者從不活躍狀態(tài)到活躍狀態(tài)時(shí)總是能收到最新的數(shù)據(jù)鸵钝。
解決Configuration Change問(wèn)題恩商,在屏幕發(fā)生旋轉(zhuǎn)或者被回收再次啟動(dòng)怠堪,立刻就能收到最新的數(shù)據(jù)。
談一談Android Architecture Components
Android Architecture Components的核心是Lifecycle锤窑、LiveData、ViewModel 以及 Room探橱,通過(guò)它可以非常優(yōu)雅的讓數(shù)據(jù)與界面進(jìn)行交互隧膏,并做一些持久化的操作胞枕,高度解耦,自動(dòng)管理生命周期决乎,而且不用擔(dān)心內(nèi)存泄漏的問(wèn)題构诚。
Room
一個(gè)強(qiáng)大的SQLite對(duì)象映射庫(kù)范嘱。
ViewModel
一類(lèi)對(duì)象,它用于為UI組件提供數(shù)據(jù)叠聋,在設(shè)備配置發(fā)生變更時(shí)依舊可以存活碌补。
LiveData一個(gè)可感知生命周期脑慧、可被觀察的數(shù)據(jù)容器砰盐,它可以存儲(chǔ)數(shù)據(jù)岩梳,還會(huì)在數(shù)據(jù)發(fā)生改變時(shí)進(jìn)行提醒。
Lifecycle
包含LifeCycleOwer和LifecycleObserver也物,分別是生命周期所有者和生命周期感知者滑蚯。
Android Architecture Components的特點(diǎn)
數(shù)據(jù)驅(qū)動(dòng)型編程
變化的永遠(yuǎn)是數(shù)據(jù)告材,界面無(wú)需更改斥赋。
感知生命周期产艾,防止內(nèi)存泄漏
高度解耦
數(shù)據(jù),界面高度分離隘膘。
數(shù)據(jù)持久化
數(shù)據(jù)棘幸、ViewModel不與 UI的生命周期掛鉤,不會(huì)因?yàn)榻缑娴闹亟ǘN(xiāo)毀吨悍。
重點(diǎn):為什么使用LiveData構(gòu)建數(shù)據(jù)通信總線(xiàn)LiveDataBus
LiveDataBus原理圖
LiveDataBus的實(shí)現(xiàn)
第一個(gè)實(shí)現(xiàn):
publicfinalclassLiveDataBus{
privatefinalMap>?bus;
privateLiveDataBus(){
bus?=newHashMap<>();
}
privatestaticclassSingletonHolder{
privatestaticfinalLiveDataBus?DATA_BUS?=newLiveDataBus();
}
publicstaticLiveDataBusget(){
returnSingletonHolder.DATA_BUS;
}
publicMutableLiveData<T>?getChannel(String?target,?Class<T>?type){
if(!bus.containsKey(target))?{
bus.put(target,newMutableLiveData<>());
}
return(MutableLiveData)?bus.get(target);
}
publicMutableLiveDatagetChannel(String?target){
returngetChannel(target,?Object.class);
}
}
短短二十行代碼育瓜,就實(shí)現(xiàn)了一個(gè)通信總線(xiàn)的全部功能躏仇,并且還具有生命周期感知功能焰手,并且使用起來(lái)也及其簡(jiǎn)單:
注冊(cè)訂閱:
LiveDataBus.get().getChannel("key_test",?Boolean.class)
.observe(this,new?Observer()?{
@Override
publicvoidonChanged(@NullableBoolean?aBoolean)?{
}
});
發(fā)送消息:
LiveDataBus.get().getChannel("key_test").setValue(true);
我們發(fā)送了一個(gè)名為"key_test"书妻,值為true的事件躲履。
這個(gè)時(shí)候訂閱者就會(huì)收到消息聊闯,并作相應(yīng)的處理菱蔬,非常簡(jiǎn)單。
問(wèn)題出現(xiàn)
對(duì)于LiveDataBus的第一版實(shí)現(xiàn)魏身,我們發(fā)現(xiàn),在使用這個(gè)LiveDataBus的過(guò)程中李皇,訂閱者會(huì)收到訂閱之前發(fā)布的消息。對(duì)于一個(gè)消息總線(xiàn)來(lái)說(shuō)茧跋,這是不可接受的瘾杭。無(wú)論EventBus或者RxBus粥烁,訂閱方都不會(huì)收到訂閱之前發(fā)出的消息。對(duì)于一個(gè)消息總線(xiàn)芥永,LiveDataBus必須要解決這個(gè)問(wèn)題埋涧。
問(wèn)題分析
怎么解決這個(gè)問(wèn)題呢奇瘦?先分析下原因:
當(dāng)LifeCircleOwner的狀態(tài)發(fā)生變化的時(shí)候耳标,會(huì)調(diào)用LiveData.ObserverWrapper的activeStateChanged函數(shù),如果這個(gè)時(shí)候ObserverWrapper的狀態(tài)是active纲仍,就會(huì)調(diào)用LiveData的dispatchingValue郑叠。
在LiveData的dispatchingValue中乡革,又會(huì)調(diào)用LiveData的considerNotify方法沸版。
在LiveData的considerNotify方法中视粮,紅框中的邏輯是關(guān)鍵蕾殴,如果ObserverWrapper的mLastVersion小于LiveData的mVersion,就會(huì)去回調(diào)mObserver的onChanged方法茴肥。而每個(gè)新的訂閱者荡灾,其version都是-1批幌,LiveData一旦設(shè)置過(guò)其version是大于-1的(每次LiveData設(shè)置值都會(huì)使其version加1),這樣就會(huì)導(dǎo)致LiveDataBus每注冊(cè)一個(gè)新的訂閱者郁稍,這個(gè)訂閱者立刻會(huì)收到一個(gè)回調(diào)耀怜,即使這個(gè)設(shè)置的動(dòng)作發(fā)生在訂閱之前财破。
問(wèn)題原因總結(jié)
對(duì)于這個(gè)問(wèn)題左痢,總結(jié)一下發(fā)生的核心原因俊性。對(duì)于LiveData描扯,其初始的version是-1,當(dāng)我們調(diào)用了其setValue或者postValue典徊,其vesion會(huì)+1卒落;對(duì)于每一個(gè)觀察者的封裝ObserverWrapper儡毕,其初始version也為-1扑媚,也就是說(shuō),每一個(gè)新注冊(cè)的觀察者檐盟,其version為-1葵萎;當(dāng)LiveData設(shè)置這個(gè)ObserverWrapper的時(shí)候羡忘,如果LiveData的version大于ObserverWrapper的version磕昼,LiveData就會(huì)強(qiáng)制把當(dāng)前value推送給Observer票从。
如何解決這個(gè)問(wèn)題
明白了問(wèn)題產(chǎn)生的原因之后峰鄙,我們來(lái)看看怎么才能解決這個(gè)問(wèn)題。很顯然魁蒜,根據(jù)之前的分析兜看,只需要在注冊(cè)一個(gè)新的訂閱者的時(shí)候把Wrapper的version設(shè)置成跟LiveData的version一致即可狭瞎。
那么怎么實(shí)現(xiàn)呢脚作,看看LiveData的observe方法,他會(huì)在步驟1創(chuàng)建一個(gè)LifecycleBoundObserver劣针,LifecycleBoundObserver是ObserverWrapper的派生類(lèi)捺典。然后會(huì)在步驟2把這個(gè)LifecycleBoundObserver放入一個(gè)私有Map容器mObservers中襟己。無(wú)論ObserverWrapper還是LifecycleBoundObserver都是私有的或者包可見(jiàn)的,所以無(wú)法通過(guò)繼承的方式更改LifecycleBoundObserver的version员咽。
那么能不能從Map容器mObservers中取到LifecycleBoundObserver贮预,然后再更改version呢仿吞?答案是肯定的,通過(guò)查看SafeIterableMap的源碼我們發(fā)現(xiàn)有一個(gè)protected的get方法峡迷。因此绘搞,在調(diào)用observe的時(shí)候看杭,我們可以通過(guò)反射拿到LifecycleBoundObserver挟伙,再把LifecycleBoundObserver的version設(shè)置成和LiveData一致即可尖阔。
對(duì)于非生命周期感知的observeForever方法來(lái)說(shuō)介却,實(shí)現(xiàn)的思路是一致的齿坷,但是具體的實(shí)現(xiàn)略有不同。observeForever的時(shí)候崎场,生成的wrapper不是LifecycleBoundObserver谭跨,而是AlwaysActiveObserver(步驟1),而且我們也沒(méi)有機(jī)會(huì)在observeForever調(diào)用完成之后再去更改AlwaysActiveObserver的version蛮瞄,因?yàn)樵趏bserveForever方法體內(nèi)挂捅,步驟3的語(yǔ)句籍凝,回調(diào)就發(fā)生了苗缩。
那么對(duì)于observeForever酱讶,如何解決這個(gè)問(wèn)題呢泻肯?既然是在調(diào)用內(nèi)回調(diào)的灶挟,那么我們可以寫(xiě)一個(gè)ObserverWrapper稚铣,把真正的回調(diào)給包裝起來(lái)墅垮。把ObserverWrapper傳給observeForever算色,那么在回調(diào)的時(shí)候我們?nèi)z查調(diào)用棧,如果回調(diào)是observeForever方法引起的峡钓,那么就不回調(diào)真正的訂閱者能岩。
LiveDataBus最終實(shí)現(xiàn)
publicfinalclassLiveDataBus{
privatefinalMap>?bus;
privateLiveDataBus(){
bus?=newHashMap<>();
}
privatestaticclassSingletonHolder{
privatestaticfinalLiveDataBus?DEFAULT_BUS?=newLiveDataBus();
}
publicstaticLiveDataBusget(){
returnSingletonHolder.DEFAULT_BUS;
}
publicMutableLiveData<T>?with(String?key,?Class<T>?type){
if(!bus.containsKey(key))?{
bus.put(key,newBusMutableLiveData<>());
}
return(MutableLiveData)?bus.get(key);
}
publicMutableLiveDatawith(String?key){
returnwith(key,?Object.class);
}
privatestaticclassObserverWrapperimplementsObserver{
privateObserver?observer;
publicObserverWrapper(Observer<T>?observer){
this.observer?=?observer;
}
@Override
publicvoidonChanged(@Nullable?T?t){
if(observer?!=null)?{
if(isCallOnObserve())?{
return;
}
observer.onChanged(t);
}
}
privatebooleanisCallOnObserve(){
StackTraceElement[]?stackTrace?=?Thread.currentThread().getStackTrace();
if(stackTrace?!=null&&?stackTrace.length?>0)?{
for(StackTraceElement?element?:?stackTrace)?{
if("android.arch.lifecycle.LiveData".equals(element.getClassName())?&&
"observeForever".equals(element.getMethodName()))?{
returntrue;
}
}
}
returnfalse;
}
}
privatestaticclassBusMutableLiveDataextendsMutableLiveData{
privateMap?observerMap?=newHashMap<>();
@Override
publicvoidobserve(@NonNull?LifecycleOwner?owner,?@NonNull?Observer<T>?observer){
super.observe(owner,?observer);
try{
hook(observer);
}catch(Exception?e)?{
e.printStackTrace();
}
}
@Override
publicvoidobserveForever(@NonNull?Observer<T>?observer){
if(!observerMap.containsKey(observer))?{
observerMap.put(observer,newObserverWrapper(observer));
}
super.observeForever(observerMap.get(observer));
}
@Override
publicvoidremoveObserver(@NonNull?Observer<T>?observer){
Observer?realObserver?=null;
if(observerMap.containsKey(observer))?{
realObserver?=?observerMap.remove(observer);
}else{
realObserver?=?observer;
}
super.removeObserver(realObserver);
}
privatevoidhook(@NonNull?Observer<T>?observer)throwsException{
//get?wrapper's?version
????????????Class<LiveData>?classLiveData?=?LiveData.class;
????????????Field?fieldObservers?=?classLiveData.getDeclaredField("mObservers");
????????????fieldObservers.setAccessible(true);
????????????Object?objectObservers?=?fieldObservers.get(this);
????????????Class<?>?classObservers?=?objectObservers.getClass();
????????????Method?methodGet?=?classObservers.getDeclaredMethod("get",?Object.class);
????????????methodGet.setAccessible(true);
????????????Object?objectWrapperEntry?=?methodGet.invoke(objectObservers,?observer);
????????????Object?objectWrapper?=?null;
????????????if?(objectWrapperEntry?instanceof?Map.Entry)?{
????????????????objectWrapper?=?((Map.Entry)?objectWrapperEntry).getValue();
????????????}
????????????if?(objectWrapper?==?null)?{
????????????????throw?new?NullPointerException("Wrapper?can?not?be?bull!");
????????????}
????????????Class<?>?classObserverWrapper?=?objectWrapper.getClass().getSuperclass();
????????????Field?fieldLastVersion?=?classObserverWrapper.getDeclaredField("mLastVersion");
????????????fieldLastVersion.setAccessible(true);
????????????//get?livedata's?version
????????????Field?fieldVersion?=?classLiveData.getDeclaredField("mVersion");
????????????fieldVersion.setAccessible(true);
????????????Object?objectVersion?=?fieldVersion.get(this);
????????????//set?wrapper's?version
????????????fieldLastVersion.set(objectWrapper,?objectVersion);
????????}
????}
}
注冊(cè)訂閱:
LiveDataBus.get()
.with("key_test",?String.class)
.observe(this,new?Observer()?{
@Override
publicvoidonChanged(@NullableString?s)?{
}
});
發(fā)送消息:
LiveDataBus.get().with("key_test").setValue(s);
源碼說(shuō)明
LiveDataBus的源碼可以直接拷貝使用,也可以前往作者的GitHub倉(cāng)庫(kù)查看下載:
https://github.com/JeremyLiao/LiveDataBus
總結(jié)
本文提供了一個(gè)新的消息總線(xiàn)框架——LiveDataBus炭庙。訂閱者可以訂閱某個(gè)消息通道的消息焕蹄,發(fā)布者可以把消息發(fā)布到消息通道上阀溶。利用LiveDataBus银锻,不僅可以實(shí)現(xiàn)消息總線(xiàn)功能,而且對(duì)于訂閱者鼎姐,他們不需要關(guān)心何時(shí)取消訂閱炕桨,極大減少了因?yàn)橥浫∠嗛喸斐傻膬?nèi)存泄漏風(fēng)險(xiǎn)肯腕。