Android EventBus官方文檔學習

原理

官方說明

這是官方的一張圖片說明,很能說明問題,畢竟官方是最權威的

Android傳統的Intent,Handler,Broadcast或接口函數,在Fragment,Activity,Service線程之間傳遞數據,執行方法,這樣做消息的發送者和接收者之間耦合就很高,

EventBus可以替代它們,將發佈者和接收者(也說是訂閱者)之間分離,
通過解耦發佈者和訂閱者簡化Android事件傳遞

說白了EventBus就是 觀察者設計模式

使用步驟:

1. 將EventBus導入項目

Gradle 依賴 compile 'org.greenrobot:eventbus:3.0.0'

2. 定義事件-也就是傳遞的數據

(也就是一個沒有任何特別要求的Java實體類)

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

2. 準備觀察者(也就是消息的接收者)

  • 觀察者需要實現事件處理方法,當事件消息被髮送時,此方法將會被調用。
// This method will be called when a MessageEvent is posted (in the UI thread for Toast)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
    Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}

// This method will be called when a SomeOtherEvent is posted
@Subscribe
public void handleSomethingElse(SomeOtherEvent event) {
    doSomethingWith(event);
}
  • 觀察者必須先要註冊才能接收事件event(註銷),在activity和fragment中,可以根據生命週期來註冊和註銷EventBus.
@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}
@Override
public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

3. 發送消息事件

你可以在任何地方發送消息,所有的已經註冊的、並且匹配消息事件類型的觀察者(消息接收者)都會收到該事件

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

注意:在寫接收消息的方法是,方法名可以自定義,權限必須是public,參數必須是一個只要接收的參數類型是一致的,那麼四個方法都可以接收到發送的信息

事件分發的線程:

處理多線程問題

1. ThreadMode.MAIN

表示這個方法在主線程中執行(適合做異步加載,可以將子線程加載到數據直接設置到UI界面裏)

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void MessageEventBus(EventBusMessage eventBusMessage){
       //在TextView顯示接收的消息,從這個類裏拿屬性.
       tv_title.setText(eventBusMessage.Message);
       Log.d("eventBusThread","ThreadMode.MAIN "+Thread.currentThread().getName());
    }

2. ThreadMode.POSTING

表示該方法和消息發送方在同一個線程.

    @Subscribe(threadMode = ThreadMode.POSTING)
    public void MessageEventBus1(EventBusMessage eventBusMessage){
       Log.d("eventBusThread","ThreadMode.POSTING "+Thread.currentThread().getName());
    }

3. ThreadMode.ASYNC

  1. 也表示在後臺執行(也就是子線程執行),可以異步併發處理
    (適用於多個線程任務處理,內部有線程池管理,比如請求網絡時,用這個方法,他會自動創建線程去請求)
  2. 無論發佈者是在子線程還是主線程,該方法都會創建一個子線程,在子線程執行.
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void MessageEventBus2(EventBusMessage eventBusMessage){
       Log.d("eventBusThread","ThreadMode.ASYNC "+Thread.currentThread().getName());
    } 

4. ThreadMode.BACKGROUND

  1. 表示該方法在後臺運行(也就是子線程),不能夠併發處理
  2. 如果發佈者在子線程,那麼該方法就在子線程執行
  3. 如果發佈者在主線程,那麼該方法就會創建一個子線程,在子線程運行.
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void MessageEventBus3(EventBusMessage eventBusMessage){
       Log.d("eventBusThread","ThreadMode.BACKGROUND "+Thread.currentThread().getName());

    }

EventBus的黏性事件使用

一些帶有重要數據的事件發佈,例如,一個事件信號,一些初始化完成。或者如果你有傳感器位置數據和你想抓住最近的值。 這些重要信息不需要我們來緩存,使用sticky event就可以了,EventBus會緩存最近發送的sticky event事件,然後sticky event可以交付給用戶或顯式查詢。你不需要任何特殊的邏輯來考慮可用的數據。


如果一個sticky event在一段時間之前發送了

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

現在有一個activity啓動了,在註冊的期間,所有的sticky觀察者方法,將會立刻收到之前發送的sticky event.

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

// UI updates must run on MainThread
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {   
    textField.setText(event.message);
}

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

正因爲上面所說的,所以有時需要手動檢查事件,還可能需要刪除事件,這樣他們不會被髮送了。這裏是removeStickyEvent方法

MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
// Better check that an event was actually posted before
if(stickyEvent != null) {
    // "Consume" the sticky event
    EventBus.getDefault().removeStickyEvent(stickyEvent);
    // Now do something with it
}

我們也可以重寫上面的方法,如下:

MessageEvent stickyEvent = EventBus.getDefault().removeStickyEvent(MessageEvent.class);
// Better check that an event was actually posted before
if(stickyEvent != null) {
    // Now do something with it
}

這裏是參考的文檔,如果上面的看不明白,可以參考一下官方文檔

官方引導

官方文檔

百度百科

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章