一、簡單介紹
EventBus是一種能夠簡化各組件間的通信,通過解耦發(fā)布者和訂閱者簡化Android事件傳遞用以代替Android傳統(tǒng)的Intent,Handler,Broadcast或接口函數(shù),在Fragment,Activity,Service線程之間傳遞數(shù)據(jù),執(zhí)行方法。
優(yōu)勢:
簡化了組件間的通訊,是一種發(fā)布訂閱設(shè)計模式(觀察者設(shè)計模式)。
分離了事件的發(fā)送者和接受者。
- 在Activity、Fragment和線程中表現(xiàn)良好。
- 避免了復(fù)雜的和易錯的依賴關(guān)系和生命周期問題。
- 使得代碼更簡潔,性能更好。
概念:
- Event 事件。它可以是任意類型。
- Subscriber 事件訂閱者,使用需要加上注解@subscribe(),并且指定線程模型,默認(rèn)是POSTING。
- Publisher 事件的發(fā)布者。我們可以在任意線程里發(fā)布事件,一般情況下,使用EventBus.getDefault()就可以得到一個EventBus對象,然后再調(diào)用post(Object)方法即可。
線程模型:
- POSTING (默認(rèn)) 表示事件處理函數(shù)的線程跟發(fā)布事件的線程在同一個線程。
- MAIN 表示事件處理函數(shù)的線程在主線程(UI)線程,因此在這里不能進行耗時操作。
- BACKGROUND 表示事件處理函數(shù)的線程在后臺線程,因此不能進行UI操作。如果發(fā)布事件的線程是主線程(UI線程),那么事件處理函數(shù)將會開啟一個后臺線程,如果果發(fā)布事件的線程是在后臺線程,那么事件處理函數(shù)就使用該線程。
- ASYNC 表示無論事件發(fā)布的線程是哪一個,事件處理函數(shù)始終會新建一個子線程運行,同樣不能進行UI操作。
二、簡單使用
1、添加依賴,EventBus網(wǎng)址。
implementation 'org.greenrobot:eventbus:3.1.1'
2、構(gòu)造事件(Event)對象(發(fā)送消息類)。
/**
* Created by Active_Loser on 2018/9/20
* Content:簡單的提示事件
*/
public class ToastEvent {
private String content;
public ToastEvent(String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
3、注冊/解除事件訂閱
在onCreate()中通過register(this)來表示該訂閱者進行了訂閱
EventBus.getDefault().register(this);
使用注解@Subscribe,處理相關(guān)操作
注意:
若在非UI線程,需要使用@Subscribe(threadMode = ThreadMode.MainThread)更新UI
設(shè)置優(yōu)先級:@Subscribe(priority = 100)
@Subscribe
public void onToastEvent(ToastEvent event){ Toast.makeText(MainActivity.this,event.getContent(),Toast.LENGTH_SHORT).show();
}
在onDestory()方法中進行解除訂閱。
EventBus.getDefault().unregister(this);
4、發(fā)送事件,發(fā)送消息
EventBus.getDefault().post(new ToastEvent("我是一個toast!"));
三、粘性事件
訂閱在發(fā)布事件之后,但同樣可以收到事件。訂閱/解除訂閱和普通事件一樣,但是處理訂閱的方法有所不同,需要注解中添加sticky = true。
@Subscribe(sticky = true)
public void onToastEvent(ToastEvent event){
Toast.makeText(MainActivity.this,event.getContent(),Toast.LENGTH_SHORT).show();
EventBus.getDefault().cancelEventDelivery(event);
}
}
當(dāng)設(shè)置了sticky = true,在ToastEvent 的事件發(fā)布后,進行注冊。依然能夠接收到之前發(fā)布的事件。
EventBus.getDefault().postSticky(new ToastEvent("Toast,發(fā)個提示,祝大家新年快樂!"));
移除
EventBus.getDefault().removeStickyEvent(ToastEvent.class);
//移除所有粘性事件
EventBus.getDefault().removeAllStickyEvents();