(參考)https://blog.csdn.net/itachi85/article/details/52205464
EventBus是一款針對Android優化的發布/訂閱事件總線。簡化了應用程序內各組件間、組件與后臺線程間的通信。
優點:
開銷小,代碼更優雅,以及將發送者和接收者解耦。如果Activity和Activity進行交互還好說,如果Fragment和Fragment進行交互著實令人頭疼,我們會使用廣播來處理,但是使用廣播稍顯麻煩并且效率也不高,如果傳遞的數據是實體類需要序列化,那么很顯然成本會有點高。
三個組成元素:
Event:事件,可以是任意類型的對象。
Subscriber:事件訂閱者,在EventBus3.0之前消息處理的方法只能限定于onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,他們分別代表四種線程模型。而在EventBus3.0之后,事件處理的方法可以隨便取名,但是需要添加一個注解@Subscribe,并且要指定線程模型(默認為POSTING),四種線程模型下面會講到。
Publisher:事件發布者,可以在任意線程任意位置發送事件,直接調用EventBus的post(Object)方法。可以自己實例化EventBus對象,但一般使用EventBus.getDefault()就好了,根據post函數參數的類型,會自動調用訂閱相應類型事件的函數。
四種ThreadMode:
POSTING(默認):如果使用事件處理函數指定了線程模型為POSTING,那么該事件在哪個線程發布出來的,事件處理函數就會在這個線程中運行,也就是說發布事件和接收事件在同一個線程。在線程模型為POSTING的事件處理函數中盡量避免執行耗時操作,因為它會阻塞事件的傳遞,甚至有可能會引起ANR。
MAIN: 事件的處理會在UI線程中執行。事件處理時間不能太長,長了會ANR的。
BACKGROUND:如果事件是在UI線程中發布出來的,那么該事件處理函數就會在新的線程中運行,如果事件本來就是子線程中發布出來的,那么該事件處理函數直接在發布事件的線程中執行。在此事件處理函數中禁止進行UI更新操作。
ASYNC:無論事件在哪個線程發布,該事件處理函數都會在新建的子線程中執行,同樣,此事件處理函數中禁止進行UI更新操作。
基本用法:
步驟1:自定義一個事件類
public class MessageEvent {...}
例子:
public class FirstEvent{
private String msg;
public FirstEvent(String msg){
? ? ? this.msg = msg;
? ? }
public String getMsg(){
? ? ? return msg;
? ? }
}
步驟2:在需要訂閱事件的地方注冊事件
EventBus.getDefault().register(this);
步驟3:發送事件
EventBus.getDefault().post(messageEvent);
另外:發送粘性事件:
EventBus.getDefault().postSticky(new MessageEvent("粘性事件"));
步驟4:.處理事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void XXX(MessageEvent messageEvent) {
...
}
另外:粘性事件接收,在發送事件之后再訂閱該事件也能收到該事件,跟黏性廣播類似。
@Subscribe(threadMode = ThreadMode.POSTING,sticky = true)
? ? public void ononMoonStickyEvent(MessageEvent messageEvent){
? ? ? ? tv_message.setText(messageEvent.getMessage());
? ? }
sticky:默認為false,如果為true,當通過postSticky發送一個事件時,這個類型的事件的最后一次事件會被緩存起來,當有訂閱者注冊時,會把之前緩存起來的這個事件直接發送給它。使用在比如事件發送者先啟動了,訂閱者還沒啟動的情況。
priority:默認值為0。訂閱了同一個事件的訂閱函數,在ThreadMode值相同的前提下,收到事件的優先級。
步驟5:取消事件訂閱
EventBus.getDefault().unregister(this);
一般都在onDestory()方法中取消注冊,釋放資源
@Override protected void onDestroy() {
? ? ? ? super.onDestroy();
? ? ? ? //取消注冊事件? ? ??
? ? ? ?EventBus.getDefault().unregister(this);
? ? }