我在實(shí)際項(xiàng)目中使用EventBus經(jīng)驗(yàn)總結(jié):
創(chuàng)新互聯(lián)建站堅(jiān)實(shí)的技術(shù)研發(fā)基礎(chǔ)贏得了行業(yè)內(nèi)的良好口碑,公司成立10余年來,為上千企業(yè)提供過網(wǎng)站建設(shè)、軟件開發(fā)、搜索引擎優(yōu)化技術(shù)、互聯(lián)網(wǎng)大數(shù)據(jù)整合營銷服務(wù),多年的技術(shù)服務(wù)成功經(jīng)驗(yàn)、眾多的客戶使我們能懂得更多,做得更好。"讓您的網(wǎng)站跑起來"是我們一直追求的目標(biāo)!
剛開始聽到EventBus的時(shí)候,覺得好像比較高大上,沒有學(xué)過,不敢用。但是還是情不自禁的用到了項(xiàng)目當(dāng)中。但是隨著EventBus使用的地方越多,問題就出現(xiàn)了,就像見了鬼一樣。
問題1
》描述:比如在Activity里有2個(gè)或多個(gè)Fragment,在兩個(gè)Fragment里都會在子線程中發(fā)布
MessageEvent在UI線程里吐司。但是問題來了,在FragmentA里我會請求網(wǎng)絡(luò),然后我又到了
FragmentB中,竟然會接受到了FragmentA里的消息事件。
》原因分析:既然在Fragment里可以接受到FragmentA的消息,說明FragmentA沒有unRegist事件。
原因是我照搬網(wǎng)上的代碼,在onCreate里訂閱事件,在onDestroy里unRegist事件。
但實(shí)際上從FragmentA切換到FragmentB的時(shí)候,F(xiàn)ragmentA是沒有走onDestroy方法的。
》解析方案:于是我決定在onStart與onStop方法里來走regist與unRegist方法。
雖然這個(gè)問題解決了,但是新的問題又來了。FragmentA里的吐司事件又接收不到了,
原因是FragmentA里的事件是在onActivityCreated方法里執(zhí)行的,而這個(gè)生命周期的方
法又是在onStart之前執(zhí)行的。所以當(dāng)請求網(wǎng)絡(luò)回調(diào)發(fā)布事件的時(shí)候,還沒有訂閱事件。
于是乎,我做了一個(gè)雙重保險(xiǎn):
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EventBus.getDefault().register(this); } @Override public void onStart() { super.onStart(); if(!EventBus.getDefault().isRegistered(this)){ EventBus.getDefault().register(this); } } @Override public void onStop() { super.onStop(); EventBus.getDefault().unregister(this); } @Override public void onDestroyView() { super.onDestroyView(); ButterKnife.reset(this); if(EventBus.getDefault().isRegistered(this)){ EventBus.getDefault().unregister(this); } }
問題2
搞開發(fā)就是這樣,問題問題層出不窮。
》描述:進(jìn)入登錄Fragment,沒有點(diǎn)擊登錄按鈕就退出了。竟然還解析了登錄,并且登錄的吐司竟然彈在了主頁上。
》原因分析:最開始,打的bug竟然沒有走,后來又走了,才找到原因。事件定義重復(fù)了,主頁在
onResume里請求網(wǎng)絡(luò)會發(fā)布一個(gè)事件,因?yàn)槭录膇nt類型與登錄Fragment里訂閱的登錄
解析事件的int型相重復(fù)。但是即使是這樣,登錄Fragment關(guān)閉了不可能接收到主頁的事
件啊。主要原因還是因?yàn)榈卿汧ragment的onDestroy方法有延遲,登錄Fragment雖然不
見了,但是觸發(fā)了主頁Fragment的onResume事件,登錄Fragment沒有來得及取消訂閱就
接受到了主頁Fragment的登錄解析事件,然后又把吐司給主頁Fragment了。
》解決方案:只要將沖突的事件int類型值改一下就行了。
綜上所述,EventBus訂閱與取消訂閱要及時(shí)準(zhǔn)確(對所在類的生命周期把握準(zhǔn)確),事件的定義(不同事件一定要有唯一標(biāo)識),另外還有一點(diǎn),事件類容易越寫越多,要注意重構(gòu)抽取。
EventBus概論
EventBus是Google Guava庫里的一個(gè)類,用來進(jìn)行消息傳遞,線程之間通訊。
2.EventBus的使用
首先必須要入庫
onCreate() 注冊EventBus EventBus.register(Object ),注冊的對象決定發(fā)布事件的參數(shù)
所在方法的反射范圍,一般用this,表示掃描當(dāng)前類中所有的方法。
onDestroy() 注銷EventBus EventBus.unRegister(Object)
發(fā)布事件:EventBus.post(參數(shù)) 參數(shù)可以是任何類型,一般為實(shí)體類。
一般在子線程中發(fā)布獲得的數(shù)據(jù),然后通過在主線程中的方法來接收參數(shù),并更新UI。
注意:處理事件的方法一定要加上@Subscribe注解
3.EventBus的底層
EventBus的底層是用反射、集合Map技術(shù)。具體請看源碼。
資料拓展:http://blog.csdn.net/lmj623565791/article/details/40794879
http://m.blog.csdn.net/blog/u013173289/43970023