EventBus 用法詳解

EventBus


概述

EventBus是一款針對Android優化的發佈/訂閱(publish/subscribe)事件總線。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,線程之間傳遞消息。簡化了應用程序內各組件間、組件與後臺線程間的通信。優點是開銷小,代碼更優雅。以及將發送者和接收者解耦。比如請求網絡,等網絡返回時通過Handler或Broadcast通知UI,兩個Fragment之間需要通過Listener通信,這些需求都可以通過EventBus實現。

EventBus作爲一個消息總線,有三個主要的元素:

  • Event:事件。可以是任意類型的對象
  • Subscriber:事件訂閱者,接收特定的事件。在EventBus中,使用約定來指定事件訂閱者以簡化使用。即所有事件訂閱都都是以onEvent開頭的函數,具體來說,函數的名字是onEvent,onEventMainThread,onEventBackgroundThread,onEventAsync這四個,這個和
    ThreadMode(下面講)有關。
  • Publisher:事件發佈者,用於通知 Subscriber 有事件發生。可以在任意線程任意位置發送事件,直接調用eventBus.post(Object) 方法,可以自己實例化 EventBus
    對象,但一般使用默認的單例就好了:EventBus.getDefault(), 根據post函數參數的類型,會自動調用訂閱相應類型事件的函數。

關於ThreadMode

前面說了,Subscriber的函數只能是那4個,因爲每個事件訂閱函數都是和一個ThreadMode相關聯的,ThreadMode指定了會調用的函數。有以下四個ThreadMode:

  • PostThread:事件的處理在和事件的發送在相同的進程,所以事件處理時間不應太長,不然影響事件的發送線程,而這個線程可能是UI線程。對應的函數名是onEvent。
  • MainThread: 事件的處理會在UI線程中執行。事件處理時間不能太長,這個不用說的,長了會ANR的,對應的函數名是onEventMainThread。
  • BackgroundThread:事件的處理會在一個後臺線程中執行,對應的函數名是onEventBackgroundThread,雖然名字是BackgroundThread,事件處理是在後臺線程,但事件處理時間還是不應該太長,因爲如果發送事件的線程是後臺線程,會直接執行事件,如果當前線程是UI線程,事件會被加到一個隊列中,由一個線程依次處理這些事件,如果某個事件處理時間太長,會阻塞後面的事件的派發或處理。
  • Async:事件處理會在單獨的線程中執行,主要用於在後臺線程中執行耗時操作,每個事件會開啓一個線程(有線程池),但最好限制線程的數目。

根據事件訂閱都函數名稱的不同,會使用不同的ThreadMode,比如果在後臺線程加載了數據想在UI線程顯示,訂閱者只需把函數命名onEventMainThread。

對相應的函數名,進一步解釋一下:

onEvent:如果使用onEvent作爲訂閱函數,那麼該事件在哪個線程發佈出來的,onEvent就會在這個線程中運行,也就是說發佈事件和接收事件線程在同一個線程。使用這個方法時,在onEvent方法中不能執行耗時操作,如果執行耗時操作容易導致事件分發延遲。

onEventMainThread:如果使用onEventMainThread作爲訂閱函數,那麼不論事件是在哪個線程中發佈出來的,onEventMainThread都會在UI線程中執行,接收事件就會在UI線程中運行,這個在Android中是非常有用的,因爲在Android中只能在UI線程中跟新UI,所以在onEvnetMainThread方法中是不能執行耗時操作的。

onEventBackground:如果使用onEventBackgrond作爲訂閱函數,那麼如果事件是在UI線程中發佈出來的,那麼onEventBackground就會在子線程中運行,如果事件本來就是子線程中發佈出來的,那麼onEventBackground函數直接在該子線程中執行。

onEventAsync:使用這個函數作爲訂閱函數,那麼無論事件在哪個線程發佈,都會創建新的子線程在執行onEventAsync。

基本用法

引入EventBus:

compile 'org.greenrobot:eventbus:3.0.0'

定義事件:

public class MessageEvent { /* Additional fields if needed */ }

註冊事件接收者:

eventBus.register(this);

發送事件:

eventBus.post(event)

接收消息並處理:

// 3.0後不再要求事件以 onEvent 開頭,而是採用註解的方式
@Subscribe(threadMode = ThreadMode.MAIN)
public void receive(MessageEvent event){}

註銷事件接收:

eventBus.unregister(this);

索引加速:

3.0 後引入了索引加速(默認不開啓)的功能,即通過 apt 編譯插件的方式,在代碼編譯的時候對註解進行索引,避免了以往通過反射造成的性能損耗。
如何使用可以參考[官方文檔](http://greenrobot.org/eventbus/documentation/subscriber-index/)

最後,proguard 需要做一些額外處理:

#EventBus
 -keepclassmembers class ** {
    public void onEvent*(**);
    void onEvent*(**);
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章