1.EventBus是一個基于觀察者模式的事件發(fā)布/訂閱框架绊序,開發(fā)者通過極少的代碼去實(shí)現(xiàn)多個模塊之間的通信,而不需要以層層傳遞接口的形式去單獨(dú)構(gòu)建通信橋梁秽荞。從而降低因多重回調(diào)導(dǎo)致的模塊間強(qiáng)耦合骤公,同時避免產(chǎn)生大量內(nèi)部類。擁有使用方便扬跋,性能高阶捆,接入成本低,支持多線程的優(yōu)點(diǎn)钦听。
2.使用過程 :
? 1)導(dǎo)入: ?
0)在app的gradle的dependences里引入??compile'org.greenrobot:eventbus:3.0.0'
A)在項(xiàng)目的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進(jìn)行初始化:?
@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();
另一個例子是當(dāng)一個訂閱者拋出一個異常的失敗昔善。注意:默認(rèn)情況下翩概,EventBus捕獲異常從onEvent方法中拋出并且發(fā)出一個SubscriberExceptionEvent 钥庇,這個事件可以不必處理评姨。
EventBus eventBus= EventBus.builder().throwSubscriberException(true).build();
6)情況
PostThread:如果使用事件處理函數(shù)指定了線程模型為PostThread,那么該事件在哪個線程發(fā)布出來的蕴侧,事件處理函數(shù)就會在這個線程中運(yùn)行,也就是說發(fā)布事件和接收事件在同一個線程裹纳。在線程模型為PostThread的事件處理函數(shù)中盡量避免執(zhí)行耗時操作,因?yàn)樗鼤枞录膫鬟f朋鞍,甚至有可能會引起ANR更舞。
MainThread:如果使用事件處理函數(shù)指定了線程模型為MainThread,那么不論事件是在哪個線程中發(fā)布出來的刊头,該事件處理函數(shù)都會在UI線程中執(zhí)行。該方法可以用來更新UI污尉,但是不能處理耗時操作被碗。
BackgroundThread:如果使用事件處理函數(shù)指定了線程模型為BackgroundThread,那么如果事件是在UI線程中發(fā)布出來的焚志,那么該事件處理函數(shù)就會在新的線程中運(yùn)行云矫,如果事件本來就是子線程中發(fā)布出來的挑社,那么該事件處理函數(shù)直接在發(fā)布事件的線程中執(zhí)行。在此事件處理函數(shù)中禁止進(jìn)行UI更新操作阱当。
Async:如果使用事件處理函數(shù)指定了線程模型為Async动猬,那么無論事件在哪個線程發(fā)布,該事件處理函數(shù)都會在新建的子線程中執(zhí)行。同樣凤覆,此事件處理函數(shù)中禁止進(jìn)行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
}