EventBus是一個Android平臺上的事件發(fā)送/訂閱框架,采用觀察者模式實現(xiàn),可以優(yōu)化組件間的信息傳遞過程。

這篇筆記主要參考官方文檔,點[這里][1].
[1]: https://github.com/greenrobot/EventBus/blob/master/HOWTO.md
基本的使用
1. 定義events
Events通常是一個POJO(plain old Java object).可以根據(jù)需要,隨便定義。可以定義多種類型的events,事件處理函數(shù)根據(jù)事件的類型實現(xiàn)重載。events除了自定義,還可以是Java中的基本類型(int, boolean等)。
public class MessageEvent{
public String message;
public MessageEvent(String message){
this.message = message;
}
}
2. 注冊訂閱者
只有需要接收events的地方,才需要注冊訂閱者。只是發(fā)送事件的話,不必注冊。
在Acitvity中注冊和注銷訂閱者:
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
3. 添加events處理函數(shù)
其實添加events處理函數(shù)也是注冊訂閱者的一部分,它們倆一起完成了注冊任務(wù)。
在注冊了訂閱者的地方,添加事件處理函數(shù)。
// This method will be called when a MessageEvent is posted
public void onEvent(MessageEvent event){
Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}
// This method will be called when a SomeOtherEvent is posted
public void onEvent(SomeOtherEvent event){
doSomethingWith(event);
}
有兩點需要注意:
- 事件處理函數(shù)必須有參數(shù),且只能有一個參數(shù)。函數(shù)根據(jù)這個參數(shù)的類型,實現(xiàn)重載的功能。
- 事件處理函數(shù)的名字必須以onEvent開頭,且必須是以下四種:
- onEvent
- onEventMainThread
- onEventBackgroundThread
- onEventAsync
4. 發(fā)送events
可以在任何地方發(fā)送一個事件。所有注冊了這個事件類型的訂閱者都可以收到它。
EventBus.getDefault().post(new MessageEvent("Hello everyone!"));
這里有兩點需要注意:
- 如果event是基本類型,發(fā)送時event會被自動裝箱。因此事件處理函數(shù)(onEvent)的參數(shù)類型必須是基本類型對應(yīng)的對象類型。
- 所有注冊了event對象的父類的訂閱者,都可以收到這個event。也就是說,如果某個訂閱者的某個事件處理函數(shù)的參數(shù)是Object類型
onEvent(Object object)
那么所有發(fā)出去的event,它都可以收到。
線程模型
EventBus可以自動處理線程問題,使我們從后臺線程與UI線程的切換中解放出來。
在EventBus中,通過約定事件處理函數(shù)名稱的方式,決定在哪個線程中執(zhí)行事件處理方法。
-
onEvent
對應(yīng)PostThread模型,事件處理函數(shù)將會在事件發(fā)送者的線程上執(zhí)行。這種模式,不需要切換線程,是最快速的,推薦默認采用。 -
onEventMainThread
對應(yīng)MainThread模型,事件處理函數(shù)將會在主線程上執(zhí)行。 -
onEventBackgroundThread
對應(yīng)BackgroundThread模型,如果發(fā)送線程不是主線程,那么事件處理函數(shù)將會直接在發(fā)送線程調(diào)用。如果發(fā)送線程是主線程,那么EventBus會啟用一個后臺線程執(zhí)行事件處理函數(shù)。 -
onEventAsync
對應(yīng)Async模型,EventBus會啟用一個單獨的線程(既不是發(fā)送線程,又不是主線程)執(zhí)行事件處理函數(shù)。EventBus會使用線程池,重用線程。
設(shè)定優(yōu)先級
可以在注冊的時候,設(shè)置訂閱者的優(yōu)先級。
int priority = 1;
EventBus.getDefault().register(this, priority);
高優(yōu)先級的訂閱者,可以先接收到事件。默認的優(yōu)先級是0.
這里有一點需要注意,用官方文檔的話說就是:
Note: the priority does NOT affect the order of delivery among subscribers with different ThreadModes!
也就是說,兩個訂閱者:subscribe1和subscribe2,subscribe1的優(yōu)先級較高,那么subscribe1的onEvent函數(shù)肯定比subscribe2的onEvent函數(shù)先接收到事件,onEventBackgroundThread函數(shù)也肯定比subscribe2的onEventBackgroundThread優(yōu)先。但是不能比較subscribe1的onEvent和subscribe2的onEventBackgroundThread,因為它們的線程模型不同,可能在不同的線程上。
取消events的傳遞
高優(yōu)先級的訂閱者可以在事件處理函數(shù)中取消事件的傳遞。
// Called in the same thread (default)
public void onEvent(MessageEvent event){
// Process the event
...
EventBus.getDefault().cancelEventDelivery(event) ;
}
Sticky Events
Sticky Events可以用于需要延遲接收事件的情況。
普通的事件發(fā)送出去以后,EventBus便不再持有了,因此后續(xù)注冊的訂閱者無法接收到它。但是sticky事件不同,EventBus會在內(nèi)存中為每一種事件類型保存一個最新發(fā)送的事件,直到后續(xù)發(fā)送新的sticky事件,把它覆蓋掉。因此后續(xù)注冊的訂閱者,依然可以從內(nèi)存中得到這個已發(fā)送的sticky事件。
發(fā)送sticky事件:
EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));
注冊sticky訂閱者:
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().registerSticky(this);
}
public void onEventMainThread(MessageEvent event) {
textField.setText(event.message);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
也可以直接直接獲得某個類型的sticky事件:
EventBus.getDefault().getStickyEvent(Class<?> eventType)
有兩點需要注意:
- sticky類型的訂閱者,依然可以收到普通類型的event;但是普通類型的訂閱者收不到sticky類型的event
- 某個類型,只有最新的事件才會被保存