EventBus使用及解析
在我們剛學Android不久,就會學到用介面回撥來非同步通知事件。寫起來也算順手,但是介面回撥需要不斷地設定listener,耦合性較大,當專案越來越複雜,介面回撥的傳值會形成一張錯綜複雜的網,有這樣使用經歷的人就會深有感觸。於是,就可以使用EventBus的事件傳遞方法,在傳送著和接收者完全解耦,傳遞接收範圍廣,接下來就學習怎樣使用Eventbus。
事件產生過程

流程示意圖
EventBus的三要素
Event:事件,可以是任意型別的物件。
Subscriber:事件訂閱者,在EventBus3.0之前訊息處理的方法只能限定於onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,他們分別代表四種執行緒模型。而在EventBus3.0之後,事件處理的方法可以隨便取名,但是需要新增一個註解@Subscribe,並且要指定執行緒模型(預設為POSTING)。
Publisher:事件釋出者,可以在任意執行緒任意位置傳送事件,直接呼叫EventBus的post(Object)方法。可以自己例項化EventBus物件,但一般使用EventBus.getDefault()就好了,根據post函式引數的型別,會自動呼叫訂閱相應型別事件的函式。
使用步驟
引入庫
implementation 'org.greenrobot:eventbus:3.0.0'
這裡可以看到EventBus.getDefault()內部呼叫的是懶漢式的單例獲取Eventbus物件方法。
/** Convenience singleton for apps using a process-wide EventBus instance. */ public static EventBus getDefault() { if (defaultInstance == null) { synchronized (EventBus.class) { if (defaultInstance == null) { defaultInstance = new EventBus(); } } } return defaultInstance; }
建立傳送的實體類,根據傳送者的實體類和接收者的實體類相匹配來看是否接收事件。
public class PostMsg { private int num; private String title; public PostMsg(int num, String title) { this.num = num; this.title = title; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
在任意需要傳送事件的地方傳送訊息,對,傳送就是這麼簡單:
EventBus.getDefault().post(new PostMsg(100,"這裡是標題"));
接收訊息的地方需要在onCreate()方法中進行註冊
EventBus.getDefault().post(this);
在onDestroy()方法中取消註冊(避免記憶體洩漏)
@Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); }
接收訊息
@Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(PostMsg postMsg){ Toast.makeText(getApplicationContext(),postMsg.getNum() + "" + postMsg.getTitle(),Toast.LENGTH_LONG).show(); }
執行緒模式
public enum ThreadMode { POSTING, MAIN, BACKGROUND, ASYNC }
POSTING:訂閱者方法將在釋出事件所在的執行緒中被呼叫。是預設的執行緒模式,該模式不會切換執行緒,意味著最少的效能開銷。可能會發生下主執行緒。
MAIN:訂閱者方法將在主執行緒中被呼叫。
BACKGROUND:訂閱者方法將在後臺執行緒中被呼叫。如果釋出事件的執行緒不是主執行緒,那麼訂閱者方法將直接在該執行緒中被呼叫。如果釋出事件的執行緒是主執行緒,那麼將使用一個單獨的後臺執行緒
ASYNC:訂閱者方法將在一個單獨的執行緒中被呼叫,該模式可用來執行耗時操作。
粘性事件
當有需求需要傳送訊息,所有註冊過的Activity都能收到。但是此時只有一部分Activity建立了,那麼此時發出訊息,未建立的Activity就接收不到訊息。粘性事件就解決了該問題。通過 postSticky 傳送粘性事件,這個事件不會只被消費一次就消失,而是一直存在系統中,直到被 removeStickyEvent 刪除掉。
釋出粘性事件
EventBus.getDefault().postSticky(new PostMsg(100,"這裡是標題"));
接收粘性事件
@Subscribe(sticky = true) public void onEventMainThread(PostMsg postMsg){ }
移除指定粘性事件
//移除某種型別粘性事件 EventBus.getDefault().removeStickyEvent(ThreadMode.xxx); //移除某種物件粘性事件 EventBus.getDefault().removeStickyEvent(object); //移除所有粘性事件 EventBus.getDefault().removeAllStickyEvents();