首語
- EventBus是一個Android端優化的publish/subscribe消息總線,簡化了應用程序內各組件間、組件與後臺線程間的通信。比如請求網絡,等網絡返回時通過Handler或Broadcast通知UI,兩個Fragment之間需要通過Listener通信,這些需求都可以通過EventBus實現。實現解耦讓業務代碼更加簡潔,可以動態設置事件處理線程及優先級。
原理框圖
三要素
- Event——事件。他可以是任意類型。
- Subscriber——事件訂閱者。EventBus3.0之前必須定義OnEvent開頭的那幾個方法,分別是onEvent、onEventMainThread、onEventBackgroundThread、onEventAsync,在3.0以後,事件處理的方法名可以隨意取,不過需要加上註解@Subscribe(),並且指定線程模型,默認是POSTING。
- Pusblisher——事件的發佈者。可以在任意線程裏發佈事件,一般情況下,使用EventBus.getDefault()就可以得到一個EventBus對象,然後再調用post(Object)方法即可。
四種線程模型
- PostThread(默認)表示事件處理函數的線程跟發佈事件的線程在同一個線程。
- MainThread表示事件處理函數的線程在主(UI)線程,因此不能進行耗時操作。
- BackgroundThread表示事件處理函數的線程在後臺線程,因此不能進行UI操作,如果發佈事件的線程是主(UI)線程,那麼事件處理函數將開啓一個後臺線程。如果發佈事件的線程是在後臺線程,那麼時間處理函數就使用該線程。
- Async表示無論事件發佈的線程在哪一個,事件處理函數始終會新建一個子線程運行,同樣,不可以進行UI操作。
依賴:implementation 'org.greenrobot:eventbus:3.1.1'
基本用法
1.註冊事件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
}
2.解除註冊
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
3.構造發送事件類
public class MessageEvent {
public String name;
public String password;
public MessageEvent(String name, String password) {
this.name = name;
this.password = password;
}
}
4.發送事件
EventBus.getDefault().post(new MessageEvent("dahaige","123456"));
5.處理事件
@Subscribe(threadMode = ThreadMode.MainThread)
public void MessageEventBus(MessageEvent event){
tvData.setText(event.name);
tvTitle.setText(event.password);
}
終止事件向下傳遞
EventBus.getDefault().cancelEventDelivery(event);
粘性事件
- 粘性事件是指在EventBus內部被緩存的那些事件,發送事件之後再訂閱該事件也能收到該事件。與普通事件的區別是普通事件先註冊後綁定,才能接受到事件。粘性事件先發送事件,不需要先註冊,也能接收事件。
1.構造發送事件類
public class StickyEvent {
public String msg;
public StickyEvent(String msg) {
this.msg = msg;
}
}
2. 發送粘性事件
EventBus.getDefault().postSticky(new StickyEvent("我是粘性事件"));
3.處理粘性事件
@Subscribe(threadMode = ThreadMode.MainThread,sticky = true)
public void StickyEventBus(StickyEvent event){
tvResult.setText(event.msg);
}
4.註冊事件
EventBus.getDefault().register(CActivity.this);
5.解註冊
EventBus.getDefault().removeStickyEvent(new StickyEvent(tvResult.getText().toString()));
EventBus.getDefault().removeAllStickyEvents();
總結
- 優點:簡化組件之間的通信方式,實現解耦讓業務代碼更加簡潔,可以動態設置事件處理線程以及優先級。
- 缺點:目前發現唯一的缺點就是類似之前策略模式一樣的詬病,每個事件都必須自定義一個事件類,造成事件類太多,無形中加大了維護成本。