知識框架(腦圖)

EventBus腦圖
出現(xiàn)背景
- 多線程環(huán)境下容易產(chǎn)生回調(diào)地獄和異常
- Android中內(nèi)置的組件間通信方式繁多(handler、intent、broadcast等等)
解決思路

EventBus的設(shè)計思路
使用事件總線(EventBus)的publisher/subscriber模式進(jìn)行解耦,解決組件間通信和多線程問題
具體步驟
(1)添加依賴庫
compile 'org.greenrobot:eventbus:3.0.0'
(2)定義事件
事件只是一個POJO(plain old java object,Java原始類型),沒有特定的要求。
public class MessageEvent {
public final String message;
public MessageEvent(String message) {
this.message = message;
}
}
(3)準(zhǔn)備訂閱者
使用注解的方式,指定方法運(yùn)行的線程 ,參數(shù)決定接收的事件,方法名任意,建議由on+事件名組成。
ThreadMode
- ThreadMode.POSTING:跟發(fā)布事件的線程一致
- ThreadMode.MAIN:在主線程中運(yùn)行
- ThreadMode.BACKGROUND:在后臺線程中運(yùn)行(非主線程則直接運(yùn)行,否則新開一個線程運(yùn)行)
- ThreadMode.ASYNC:在異步線程中運(yùn)行(不管post線程,我就是要新開一個線程運(yùn)行)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}
接著,在適當(dāng)?shù)臅r候注冊事件,并在適當(dāng)?shù)臅r候解注冊事件
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
(4)發(fā)送事件
可以在任何地方發(fā)送事件,然后注冊了事件的地方就會收到啦~
EventBus.getDefault().post(new MessageEvent("Hello everyone!"));
Q&A
問題1:EventBus這么簡潔,有什么缺點(diǎn)嗎?
跟RxJava相比,就是缺乏對事件的處理和再分發(fā)。它直接new一個事件,然后發(fā)布,你無法對事件進(jìn)行處理。
問題2:已經(jīng)消費(fèi)的事件還有可能重發(fā)嗎?
開啟stickyEvent。
發(fā)布事件的時候使用postSticky
EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));
而處理事件時,配置sticky = true。這樣重啟Activity的時候,先前的事件會重分發(fā),省去了使用SharePreferences/Bundle保存狀態(tài)的步驟~
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {
// UI updates must run on MainThread
textField.setText(event.message);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
當(dāng)然,當(dāng)再也不需要這個sticky Event時需要手動移除。
//移除sticky屬性,然后將事件返回
MessageEvent stickyEvent = EventBus.getDefault().removeStickyEvent(MessageEvent.class);
// Better check that an event was actually posted before
if(stickyEvent != null) {
// Now do something with it
}
問題3:可以設(shè)置訂閱者的優(yōu)先級嗎?
可以的,使用注解參數(shù)priority輕松搞定
@Subscribe(priority = 1); //默認(rèn)的是0
public void onEvent(MessageEvent event) {
…
}
問題4:可以停止事件繼續(xù)往下分發(fā)嗎?
可以的,使用cancelEventDelivery方法。高優(yōu)先級的訂閱者的特權(quán)?。?/p>
// Called in the same thread (default)
@Subscribe
public void onEvent(MessageEvent event){
// Process the event
…
EventBus.getDefault().cancelEventDelivery(event) ;
}
參考文檔
- EventBus Documentation:http://greenrobot.org/eventbus/documentation/