Android 中 EventBus 的使用

EventBus是一個很棒的工具,它可用來對程序組件進行解耦。在接下來的幾篇文章中我將會闡述如何通過它來簡化代碼,提高可讀性以及簡化測試。但在本文中我想首先討論一下爲什麼我會選擇使用EventBus。特別是我會將其與同類技術進行對比。


對比Java監聽器接口(Listener Interfaces)


在Java中,特別是Android,一個常用的模式就是使用”監聽器(Listeners)”接口。在此模式中,一個實現了監聽器接口的類必須將 自身註冊到它想要監聽的類中去。這就意味着監聽與被監聽之間屬於強關聯關係。這種關係就使得單元測試很難進行開展。Jake Wharton在他的《使用Otto解耦Android應用間通信》這篇文章中很好地闡述了這個問題,在此我就不進行展開了。


對比本地廣播管理器(LocalBroadcastManager)


另一項技術就是在組件間通過本地廣播管理器(LocalBroadcastManager)進行消息的發送與監聽。雖然這對於解耦有很好的幫助,但 它的API不如EventBus那樣簡潔。此外,如果你不注意保持Intent extras類型的一致,它還可能引發潛在的運行時/類型檢測錯誤。


考慮下面的應用場景:

  • 組件A執行一個批量異步數據庫更新操作。當成功完成時,它發送一條通知告訴更新了多少條記錄。發生錯誤時,發送一條通知包含了錯誤信息。

  • 組件B則需要知道到更新是否完成和更新了多少條記錄,以及是否有錯誤發生和錯誤信息。

使用LocalBroadcastManager,最簡單的代碼大概如下面所示。


組件A:


// when update completes successfully
Intent intent = new Intent();  
intent.setAction(FILTER_ACTION_UPDATE_SUCCESS);  
intent.putExtra(EXTRA_COUNT, count);  
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
 
...
 
// when there is an error
Intent intent = new Intent();  
intent.setAction(FILTER_ACTION_UPDATE_ERROR);  
intent.putExtra(EXTRA_ERROR_MSG, error.getMessage());  
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);


組件B:

EventBus bus = EventBus.getDefault(); // Or better yet, inject it
 
...
 
public void onEvent(UpdateCompleteEvent event){  
  // TODO - do something with event.count
}   
 
public void onEvent(UpdateErrorEvent event){  
  // TODO - do something with event.message
}   
 
...
 
bus.register(this);
 
...
 
bus.unregister(this);

如你所見,使用EventBus不僅使代碼變得清晰,而且增強了類型安全(type-safe)。當用Intent傳遞數據時,在編譯時並不能檢查
出所設的extra類型與收到時的類型一致。所以一個很常見的錯誤便是你或者你團隊中的其他人改變了Intent所傳遞的數據,但忘記了對全部的接收器
(receiver)進行更新。這種錯誤在編譯時是無法被發現的,只有在運行時纔會發現問題。

而使用EventBus所傳遞的消息則是通過你所定義的Event類。由於接收者方法是直接與這些類實例打交道,所以所有的數據均可以進行類型檢查,這樣任何由於類型不一致所導致的錯誤都可以在編譯時刻被發現。
另外就是你的Event類可以定義成任何類型。我通常會爲了表示事件而顯式地創建明確命名的類,你也通過EventBus發送/接收任何類。通過這
種方法,你就不必受限於那些只能添加到Intentextras中的簡單數據類型了。

例如,你可以發送一個和ORM(注1)模型類實例,並且在接收端直接處理與ORM操作相關的類實例。
希望我這裏給出了一個在Android中使用EventBus的強有力的應用場景案例。

在下一篇文章中我會談談我是如何使用Green Robot的EventBus中的“sticky”事件的。
注1: ORM(Object Relational Mapping,簡稱ORM,或O/RM,或O/R mapping)對象關係映射,是一種程序設計技術,用於實現面向對象編程語言裏不同類型系統的數據之間的轉換。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章