EventBus使用


本文主要翻譯自:
https://github.com/greenrobot/EventBus/blob/master/HOWTO.md

1. 功能介紹

1.1. EventBus

EventBus 是一個 Android 事件發(fā)布/訂閱框架,通過解耦發(fā)布者和訂閱者簡化 Android 事件傳遞。

1.2 主要對象

事件 (Event)
發(fā)布者 (Publisher)
訂閱者 (Subscriber)


2. 流程圖

流程圖

3. 類圖

類圖

4. 使用方法

4.1 使用EventBus三步

定義事件:

public class MessageEvent {
    public final String message;

    public MessageEvent(String message) {
        this.message = message;
    }
}

訂閱者注冊事件

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

// This method will be called when a MessageEvent is posted
public void onEvent(MessageEvent event){
    Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}

// This method will be called when a SomeOtherEvent is posted
public void onEvent(SomeOtherEvent event){
    doSomethingWith(event);
}

發(fā)布事件

EventBus.getDefault().post(new MessageEvent("Hello everyone!"));

4.2 交付線程和ThreadModes

事件可以在不同的線程之間傳遞
ThreadMode:

  • PostThread
    這是默認的模式,訂閱者會在發(fā)布者所在的線程中調(diào)用。這種模式開銷最小,避免了線程之間的切換。所以完成時間很短,并且不需要主線程參與的簡單任務(wù)建議使用這種模式。例如:
// Called in the same thread (default)
public void onEvent(MessageEvent event) {
    log(event.message);
} 
  • MainThread
    這種模式訂閱者會在主線程中調(diào)用。如果事件發(fā)布是在主線程,那么事件處理程序會立即被調(diào)用。使用這種模式事件處理必須盡快返回,以避免阻塞主線程。例如:
// Called in Android UI's main thread
public void onEventMainThread(MessageEvent event) {
    textField.setText(event.message);
}
  • BackgroundThread
    這種模式訂閱者會在后臺線程中調(diào)用。如果事件發(fā)布不在主線程,事件處理方法會直接在發(fā)布線程中調(diào)用;如果事件發(fā)布在主線程,EventBus則會依次傳遞所有的事件到一個后臺進程。使用這種模式必須盡快返回以避免阻塞后臺進程。
// Called in the background thread
public void onEventBackgroundThread(MessageEvent event){
    saveToDisk(event.message);
}
  • Async
    事件處理方法在一個單獨的線程中調(diào)用。他始終是獨立于發(fā)布線程和主線程。發(fā)布事件不需要等待事件處理方法的完成。如果使用耗時的操作應(yīng)當使用這種模式,比如連接網(wǎng)絡(luò)。應(yīng)當避免同一時間觸發(fā)大量的、長時間運行的異步處理方法,從而限制并發(fā)線程的數(shù)量。EventBus使用了線程池來有效的重用線程。
// Called in a separate thread
public void onEventAsync(MessageEvent event){
    backend.send(event.message);
}

4.3 訂閱者優(yōu)先級以及事件傳遞順序

我們可以通過定義優(yōu)先級來決定事件的傳遞順序

int priority = 1;
EventBus.getDefault().register(this, priority); 

在同一個ThreadMode中,優(yōu)先級高的訂閱者會先接收到事件。默認的優(yōu)先級是0。優(yōu)先級在不同的ThreadModes中是沒有效果的


4.4 使用EventBusBuilder配置EventBus

EventBus2.3增加了EventBusBuilder來配置EventBus。例如:配置一個當事件沒有訂閱者的時候,發(fā)布一個事件時,EventBus不做任何事情。

EventBus eventBus = EventBus.builder()
.logNoSubscriberMessages(false)
.sendNoSubscriberEvent(false).build();

更多設(shè)置請查看 EventBusBuilder 類和他的javaDoc

4.5 配置默認的EventBus實例

最簡單的方式是使用EventBus.getDefault()來獲取一個共享的EventBus實例,同時可以使用EventBusBuilder的installDefaultEventBus()來創(chuàng)建默認實例。
例如:可能需要配置一個默認的EventBus實例來將在onEvent()方法中的例外再次拋出,但是我們只想在debug模式中這樣做,因為這位導(dǎo)致app的崩潰。

EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).installDefaultEventBus();

在EventBus實例第一次使用前,這種配置只能做一次,從而確保在應(yīng)用程序中的一致性。最好的地方是在Application類中進行初始化。

4.6 取消事件發(fā)送

當取消事件發(fā)送后,后面的訂閱者就不再會接收到事件

// Called in the same thread (default)
public void onEvent(MessageEvent event){
    // Process the event 
    ...

    EventBus.getDefault().cancelEventDelivery(event) ;
}

事件通常是在較高優(yōu)先級的訂閱者中取消。取消動作僅限于運行在發(fā)布線程的事件處理方法。

4.7 sticky事件

一些事件攜帶的信息只有在其發(fā)布之后才會被關(guān)注。例如,有些事件會標記一些初始化的完成。或者一些傳感器或者位置數(shù)據(jù)需要獲取最新的值,這些情況我們就可以使用sticky事件。EventBus會在內(nèi)存中保留某種類型最新的sticky事件

EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));

在stickyEvent發(fā)布后,當有新的Activity啟動,并注冊了sticky事件,他就會立刻收到該事件

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().registerSticky(this);
}

public void onEventMainThread(MessageEvent event) {
    textField.setText(event.message);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

我們也可以來獲取指定類型的sticky事件

EventBus.getDefault().getStickyEvent(Class<?> eventType)

4.8 混淆的配置

-keepclassmembers class ** {
    public void onEvent*(**);
}

# Only required if you use AsyncExecutor
-keepclassmembers class * extends de.greenrobot.event.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

5. 加入EventBus到項目中

Gradle:

compile 'de.greenrobot:eventbus:2.4.0'

Maven:

<dependency>
<groupId>de.greenrobot</groupId>
<artifactId>eventbus</artifactId>
<version>2.4.0</version>
</dependency>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 近來在看平凡的世界,一發(fā)不可收拾,非常震撼心靈,心里面的那種觸動我真的表達不清楚。已經(jīng)很久沒有看到這么好看的電視劇...
    文淑閱讀 1,372評論 0 12
  • 概述 EventBus是一個Android事件發(fā)布/訂閱框架,通過解耦發(fā)布者和訂閱者簡化Android事件傳遞,這...
    劉滌生閱讀 78,693評論 6 57
  • 前言:EventBus出來已經(jīng)有一段時間了,github上面也有很多開源項目中使用了EventBus。所以抽空學習...
    Kerry202閱讀 1,302評論 1 2
  • 本文的EventBus,是指greenrobot的 EventBus, 主要以EventBus3.0 講解; 什么...
    Simon_z閱讀 5,193評論 2 2
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,951評論 19 139