我在實際項目中使用EventBus經驗總結:
剛開始聽到EventBus的時候,覺得好像比較高大上,沒有學過,不敢用。但是還是情不自禁的用到了項目當中。但是随着EventBus使用的地方越多,問題就出現了,就像見了鬼一樣。
問題1
》描述:比如在Activity裡有2個或多個Fragment,在兩個Fragment裡都會在子線程中釋出
MessageEvent在UI線程裡吐司。但是問題來了,在FragmentA裡我會請求網絡,然後我又到了
FragmentB中,竟然會接受到了FragmentA裡的消息事件。
》原因分析:既然在Fragment裡可以接受到FragmentA的消息,說明FragmentA沒有unRegist事件。
原因是我照搬網上的代碼,在onCreate裡訂閱事件,在onDestroy裡unRegist事件。
但實際上從FragmentA切換到FragmentB的時候,FragmentA是沒有走onDestroy方法的。
》解析方案:于是我決定在onStart與onStop方法裡來走regist與unRegist方法。
雖然這個問題解決了,但是新的問題又來了。FragmentA裡的吐司事件又接收不到了,
原因是FragmentA裡的事件是在onActivityCreated方法裡執行的,而這個生命周期的方
法又是在onStart之前執行的。是以當請求網絡回調釋出事件的時候,還沒有訂閱事件。
于是乎,我做了一個雙重保險:
<code>@Override</code>
<code>public</code> <code>void</code> <code>onCreate(Bundle savedInstanceState) {</code>
<code> </code><code>super</code><code>.onCreate(savedInstanceState);</code>
<code> </code><code>EventBus.getDefault().register(</code><code>this</code><code>);</code>
<code>}</code>
<code>public</code> <code>void</code> <code>onStart() {</code>
<code> </code><code>super</code><code>.onStart();</code>
<code> </code><code>if</code><code>(!EventBus.getDefault().isRegistered(</code><code>this</code><code>)){</code>
<code> </code><code>EventBus.getDefault().register(</code><code>this</code><code>);</code>
<code> </code><code>}</code>
<code>public</code> <code>void</code> <code>onStop() {</code>
<code> </code><code>super</code><code>.onStop();</code>
<code> </code><code>EventBus.getDefault().unregister(</code><code>this</code><code>);</code>
<code>public</code> <code>void</code> <code>onDestroyView() {</code>
<code> </code><code>super</code><code>.onDestroyView();</code>
<code> </code><code>ButterKnife.reset(</code><code>this</code><code>);</code>
<code> </code><code>if</code><code>(EventBus.getDefault().isRegistered(</code><code>this</code><code>)){</code>
<code> </code><code>EventBus.getDefault().unregister(</code><code>this</code><code>);</code>
問題2
搞開發就是這樣,問題問題層出不窮。
》描述:進入登入Fragment,沒有點選登入按鈕就退出了。竟然還解析了登入,并且登入的吐司竟然彈在了首頁上。
》原因分析:最開始,打的bug竟然沒有走,後來又走了,才找到原因。事件定義重複了,首頁在
onResume裡請求網絡會釋出一個事件,因為事件的int類型與登入Fragment裡訂閱的登入
解析事件的int型相重複。但是即使是這樣,登入Fragment關閉了不可能接收到首頁的事
件啊。主要原因還是因為登入Fragment的onDestroy方法有延遲,登入Fragment雖然不
見了,但是觸發了首頁Fragment的onResume事件,登入Fragment沒有來得及取消訂閱就
接受到了首頁Fragment的登入解析事件,然後又把吐司給首頁Fragment了。
》解決方案:隻要将沖突的事件int類型值改一下就行了。
綜上所述,EventBus訂閱與取消訂閱要及時準确(對所在類的生命周期把握準确),事件的定義(不同僚件一定要有唯一辨別),另外還有一點,事件類容易越寫越多,要注意重構抽取。
EventBus概論
EventBus是Google Guava庫裡的一個類,用來進行消息傳遞,線程之間通訊。
2.EventBus的使用
首先必須要入庫
onCreate() 注冊EventBus EventBus.register(Object ),注冊的對象決定釋出事件的參數
所在方法的反射範圍,一般用this,表示掃描目前類中所有的方法。
onDestroy() 登出EventBus EventBus.unRegister(Object)
釋出事件:EventBus.post(參數) 參數可以是任何類型,一般為實體類。
一般在子線程中釋出獲得的資料,然後通過在主線程中的方法來接收參數,并更新UI。
3.EventBus的底層
EventBus的底層是用反射、集合Map技術。具體請看源碼。
<a href="http://m.blog.csdn.net/blog/u013173289/43970023" target="_blank">http://m.blog.csdn.net/blog/u013173289/43970023</a>
本文轉自屠夫章哥 51CTO部落格,原文連結:http://blog.51cto.com/4259297/1705632,如需轉載請自行聯系原作者