實際項目開發過程中,經常遇到如下場景:不同的應用程序組件的控件間具有一定的相互關聯性,其中用戶對后者進行的某種操作會引起前者的相應改變。舉一個具體的場景:以糗事百科為例,在糗事列表頁和詳情頁頁,對於每個糗事而言,布局基本一致,在詳情頁點擊了個贊,贊的數量增加,同時贊的圖標發生了變化,此時返回到列表頁,此糗事上的贊圖標以及數量與剛剛詳情頁的需要保持一致。在舉一個例子,對於多個底部導航tab下的資訊類閱讀app,在咨詢詳情頁點擊了收藏,然后收藏成功,此時回到底部tab中的個人中心,假如個人中心中有我的收藏,同時后面顯示的是收藏數量,此時此收藏數量需要同於於剛剛用戶所進行的收藏/取消收藏而即時更改數字。凡此種種,類似需求場景非常常見。
有時候,當此類需求相對簡單時,通過接口以實現回調等方式可以完成,但是當不同組件/控件之間的關系紛繁復雜時,基於接口的方案不僅使得代碼非常繁瑣,同時是的程序邏輯很混亂,基於此,EventBus,為此類需求的實現提供了非常方便的方案。
網上已經有不少EventBus的使用介紹,在此簡單介紹下完整的使用流程。
1. 首先定義事件基類(其實不定義也可以,定義后的好處在於在同一個回調函數中直接依據不同的子類事件類型可以直接繼續邏輯上的處理,代碼和邏輯更加簡潔清晰)
1 public class BaseEvent { 2
3
4 }
2. 定義具體的事件類型(以上述收藏事件為例)
1 public class FavorEvent extends BaseEvent { 2
3 private int did; 4
5 public FavorEvent() { 6
7 } 8
9 public FavorEvent(int did) { 10 this.did = did; 11 } 12
13 public int getDid() { 14 return did; 15 } 16
17 public void setDid(int did) { 18 this.did = did; 19 } 20
21 }
3. 在需要監聽此收藏事件的地方向EventBus注冊事件監聽器
1 EventBus.getDefault().register(this);
4. 當需要取消注冊事件監聽器時
EventBus.getDefault().unregister(this);
注:Android中,當遇到如EventBus中的register時,一般的,相應都會有unregister邏輯。且經常register與unregister邏輯相互對應,處在如Activity等組件的不同生命周期中。這是因為EventBus(其他也類似)在注冊時由於是采用硬引用,存在潛在的內存泄露問題,而在相應生命周期中(如onDestroy)取消注冊,即可消除可能潛在的內存泄露問題。
5. 當事件發生時,需要通知相應事件監聽器進行相應邏輯處理
1 // 告知EventBus進行了收藏操作,讓其通知相關感興趣方(主要的是通知個人中心頁面改變我的收藏數量)
2 EventBus.getDefault().post(new FavorEvent());
6. 其他組件/監聽器具體事件邏輯
1 public void onEvent(BaseEvent event) { 2 // 接收收藏事件通知,同步處理收藏數字
3 if (event instanceof FavorEvent) { 4 // 即時更新收藏的數量(從sqlite中取得收藏數量)
5 updateFavorNum(); 6 } else if(..){ 7 ... 8 } 9 }
整個的使用流程主要也就這么多了,其中,關於子線程和UI線程之間等亦可進行類似事件通知,網上此類資料很多,不再贅述了。