使用Event Bus模式解耦Android App組件間通信

MaxIIQ 8年前發布 | 9K 次閱讀 Android開發 移動開發

轉自云在千峰的博客 

場景描述

當一個Android應用功能越來越多的時候,保證應用的各個部分之間高效的通信將變得越來越困難。

在應用中的多個地方,控件經常需要根據某個狀態來更新他們顯示的內容。這種場景常見的解決方式就是定義一個接口,需要關注該事件的控件來實現這個接口。然后事件觸發的地方來注冊/取消注冊這些對該事件感興趣的控件。

例如,陌陌依賴手機位置信息來獲取附近的用戶,所以在位置更新管理器(MmLocationManager)中定義了一個接口來監聽位置更新的事件(MmLocationListener):

interface MmLocationListener {
 void onLocationChanged(Location location);
}

然后在應用的各個需要響應該事件的地方來實現上面的接口,然后在位置更新管理器(MmLocationManager)中注冊/取消注冊事件監聽接口的實現類:

mLocationManager.get().register(this);

當不在需要監聽的時候,取消注冊

mLocationManager.get().unregister(this);

問題

上面的解決方案是沒問題的,但是不是理想方案。每個控件實現這個接口,導致這些控件和位置管理器注冊強耦合在一起。這還意味著,當單元測試的時候,您需要模擬(mocked)位置管理器來生成位置更新事件。

隨著應用功能的增加,需要監聽的事件越來越多,而越來越多的控件需要監聽不同的事件,則導致越來越多的控件需要注冊到各種事件管理器上:

// 代碼開始變得無法控制…
mLocationManager.get().register(this);
userAuthenticator.get().register(this);
settingsManager.get().register(this);
syncManager.get().register(this);
configurationMonitor.get().register(this);


注意:上面的每個事件的注冊,都要實現對應的時間更新接口。

注冊和取消注冊這些事件慢慢的會變得越來越難以管理。導致測試越來越困難,并將導致開發者的效率越來越低,同時在您的應用中越來越容易引入各種奇怪的Bug。
解決方案

為了找出該問題的優雅解決方案,從一個意想不到的的地方借鑒點經驗 ― Swing應用。 Event Bus模式 ― 也被稱為Message Bus或者發布者/訂閱者(publisher/subscriber)模式 ― 可以讓兩個組件相互通信,但是他們之間并不相互知曉。

和需要注冊各個事件的監聽器相比,一個組件現在只用在Event Bus上注冊一次即可:

bus.register(this);

上面的注冊告訴Event Bus我們現在希望接收各個事件的更新。 然后Bus檢測該類中每個帶有@Subscribe注解的函數,當相關的事件發生的時候就調用這些帶有注解的函數。

所以上面示例中的位置監聽功能,不用實現位置監聽接口和里面的函數了,只需要提供一個帶有@Subscribe注解的函數即可:

@Subscribe
public void locationChanged(LocationChangedEvent event) {
   // TODO React to location change.
}

現在Event Bus會把所有的LocationChangedEvent 事件都發送給上面的函數。

MmLocationManager 類不用注冊監聽器了,當位置改變的時候 只需要向Event Bus發布事件即可:

bus.post(new LocationChangedEvent(37.892818, -121.772608));

這樣 組件間相互解耦了,而單元測試也變得簡單了。任何事件都可以發布給Event Bus,然后Event Bus會找到對該事件感興趣的函數來調用。

注意:您也許已經發現該模式在Android上層也存在 ― Intent系統就是這樣設計的!

下面介紹兩個Android系統的Event Bus模式類庫。

Otto ― Android系統的Event Bus類庫

Otto是Square公司在他們應用中使用的Event Bus實現。從Guava中演變而來,并且專注于Android平臺。

https://github.com/square/otto

EventBus ― 另外一個由greenrobot實現的Event Bus類庫

https://github.com/greenrobot/EventBus

 




 本文由用戶 MaxIIQ 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!