AndroidEventBus - 一個更靈活的 Android 事件總線框架

jopen 9年前發布 | 18K 次閱讀 Android開發 移動開發 AndroidEventBus

AndroidEventBus Logo AndroidEventBus

這是一個Android平臺的事件總線框架, 它簡化了Activity、Fragment、Service等組件之間的交互,很大程度上降低了它們之間的耦合,使得我們的代碼更加簡潔,耦合性更低,提升我們的代碼質量。

在往下看之前,你可以考慮這么一個場景,兩個Fragment之間的通信你會怎么實現? 按照Android官方給的建議的解決方法如下: Communicating with the Activity, 思路就是Activity實現某個接口,然后在Fragment-A關聯上Activity之后將Activity強轉為接口類型,然后在某個時刻 Fragment中回調這個接口,然后再從Activity中調用Fragment-B中方法。這個過程是不是有點復雜呢? 如果你也這么覺得,那也就是你繼續看下去的理由了。

*A english readme is here README-en.md.*

基本結構

結構圖
AndroidEventBus類似于觀察者模式,通過register函數將需要訂閱事件的對象注冊到事件總線中,然后根據@Subcriber注解來查找對象中的訂閱方法,并且將這些訂閱方法和訂閱對象存儲在map中。當用戶在某個地方發布一個事件時,事件總線根據事件的參數類型和tag找到對應的訂閱者對象,最后執行訂閱者對象中的方法。這些訂閱方法會執行在用戶指定的線程模型中,比如mode=ThreadMode.ASYNC則表示該訂閱方法執行在子線程中,更多細節請看下面的說明。

與greenrobot的EventBus的不同

  1. greenrobot的EventBus是一個非常流行的開源庫,但是它在使用體驗上并不友好,例如它的訂閱函數必須以onEvent開頭,并且如果需要指定該函數運行的線程則又要根據規則將函數名加上執行線程的模式名,這么說很難理解,比如我要將某個事件的接收函數執行在主線程,那么函數名必須為onEventMainThread。那如果我一個訂閱者中有兩個參數名相同,且都執行在主線程的接收函數呢? 這個時候似乎它就沒法處理了。而且規定死了函數命名,那就不能很好的體現該函數的功能,也就是函數的自文檔性。AndroidEventBus使用注解來標識接收函數,這樣函數名不受限制,比如我可以把接收函數名寫成updateUserInfo(Person info),這樣就靈活得多了。
  2. 另一個不同就是AndroidEventBus增加了一個額外的tag來標識每個接收函數可接收的事件的tag,這類似于Broadcast中的 action,比如每個Broadcast對應一個或者多個action,當你發廣播時你得指定這個廣播的action,然后對應的廣播接收器才能收到.greenrobot的EventBus只是根據函數參數類型來標識這個函數是否可以接收某個事件,這樣導致只要是參數類型相同,任何的事件它都可以接收到,這樣的投遞原則就很局限了。比如我有兩個事件,一個添加用戶的事件, 一個刪除用戶的事件,他們的參數類型都為User,那么greenrobot的EventBus大概是這樣的:
private void onEventMainThread(User aUser) {
    // code 
}

如果你有兩個同參數類型的接收函數,并且都要執行在主線程,那如何命名呢 ? 即使你有兩個符合要求的函數吧,那么我實際上是添加用戶的事件,但是由于EventBus只根據事件參數類型來判斷接收函數,因此會導致兩個函數都會被執行。AndroidEventBus的策略是為每個事件添加一個tag,參數類型和tag共同標識一個事件的唯一性,這樣就確保了事件的精確投遞。這就是AndroidEventBus和greenrobot的EventBus的不同,但是由于本人對greenrobot的EventBus并不是很了解,很可能上述我所說的有誤,如果是那樣,歡迎您指出。

AndroidEventBus起初只是為了學習,但是在學習了EventBus的實現之后,發現它在使用上有些不便之處,我想既然我有這些感覺, 應該也是有同感之人,在開發群里交流之后,發現確實有這樣的情況。因此才將正式地AndroidEventBus以開源庫的形式推出來,希望能夠幫助到一些需要的人。當然,這個庫的成長需要大家的支持與測試,歡迎大家發 pull request。如果你需要的是一個相對穩定的庫,greenrobot的EventBus和square的otto都是非常好的選擇。



項目主頁:http://www.baiduhome.net/lib/view/home/1423187549701

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