1.EventBus是一個基于觀察者模式的事件發(fā)布/訂閱框架,開發(fā)者通過極少的代碼去實現多個模塊之間的通信,而不需要以層層傳遞接口的形式去單獨構建通信橋梁。從而降低因多重回調導致的模塊間強耦合,同時避免產生大量內部類。擁有使用方便,性能高,接入成本低,支持多線程的優(yōu)點。
2.使用過程 :
? 1)導入: ?
0)在app的gradle的dependences里引入??compile'org.greenrobot:eventbus:3.0.0'
A)在項目的gradle的dependences中引入 classpath'com.neenbedankt.gradle.plugins:android-apt:1.8'(如果使用索引的話)
B)在app的gradle中引入 (如果使用索引的話)
?applyplugin:'com.neenbedankt.android-apt'
? ? ?apt {
? ? ? ? ?arguments {
? ? ? ? ? ? ? ?eventBusIndex"com.study.sangerzhong.studyapp.MyEventBusIndex"
? ? ? ?}
?}
C)在app的gradle中引入? apt'org.greenrobot:eventbus-annotation-processor:3.0.1'
2)初始化
接受事件的activity需要對eventbus進行初始化:?
@OverridepublicvoidonStart(){
? ? ?super.onStart();? ??
? ? ? EventBus.getDefault().register(this);
}
@Override
publicvoidonStop(){?
? ? ? EventBus.getDefault().unregister(this);
? ? ? super.onStop();
}
3)接受
@Subscribe(threadMode = ThreadMode.MAIN)
?publicvoidonMessage(MessageEventevent){??
? ? ? ? ?textField.setText(event.message);
}
@Subscribe(sticky =true, threadMode = ThreadMode.MAIN)//粘性事件
publicvoidonEvent(MessageEvent event){// UI updates must run on MainThread
? ? ? ?textField.setText(event.message);? ??
}
4)發(fā)送
EventBus.getDefault().post(newMessageEvent("Hello everyone!"));
EventBus.getDefault().postSticky(newMessageEvent("Hello everyone!"));//發(fā)送粘性事件
5)自配置eventBus
EventBusBuilder用來配置EventBus。比如,如果一個提交的事件沒有訂閱者,可以使EventBus保持安靜。
EventBuseventBus = EventBus.builder().logNoSubscriberMessages(false)? ? .sendNoSubscriberEvent(false).build();
另一個例子是當一個訂閱者拋出一個異常的失敗。注意:默認情況下,EventBus捕獲異常從onEvent方法中拋出并且發(fā)出一個SubscriberExceptionEvent ,這個事件可以不必處理。
EventBus eventBus= EventBus.builder().throwSubscriberException(true).build();
6)情況
PostThread:如果使用事件處理函數指定了線程模型為PostThread,那么該事件在哪個線程發(fā)布出來的,事件處理函數就會在這個線程中運行,也就是說發(fā)布事件和接收事件在同一個線程。在線程模型為PostThread的事件處理函數中盡量避免執(zhí)行耗時操作,因為它會阻塞事件的傳遞,甚至有可能會引起ANR。
MainThread:如果使用事件處理函數指定了線程模型為MainThread,那么不論事件是在哪個線程中發(fā)布出來的,該事件處理函數都會在UI線程中執(zhí)行。該方法可以用來更新UI,但是不能處理耗時操作。
BackgroundThread:如果使用事件處理函數指定了線程模型為BackgroundThread,那么如果事件是在UI線程中發(fā)布出來的,那么該事件處理函數就會在新的線程中運行,如果事件本來就是子線程中發(fā)布出來的,那么該事件處理函數直接在發(fā)布事件的線程中執(zhí)行。在此事件處理函數中禁止進行UI更新操作。
Async:如果使用事件處理函數指定了線程模型為Async,那么無論事件在哪個線程發(fā)布,該事件處理函數都會在新建的子線程中執(zhí)行。同樣,此事件處理函數中禁止進行UI更新操作。
7)
手動獲取和移除sticky事件
就像前一段說的那樣,最后的sticky事件在訂閱者注冊的時候會自動傳遞。但是,有時候手動檢測sticky事件更方便。有時候他們不再傳遞的時候需要移除sticky事件。比如:
MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);// Bettercheckthat an event was actually posted beforeif(stickyEvent != null) {? ? //"Consume"the sticky event? ?
?EventBus.getDefault().removeStickyEvent(stickyEvent);? ? // Now do something with it
}