EventBus的粘性事件


下午趕去公司解決了電台業務首次語音搜台后(用到服務,但只出一個獨立的Activity,主界面並沒有打開)不能聽歌識曲的問題.

排查到最后,去識別的消息確實是發出去了,但是卻沒有收到,沒有收到消息當然不會響應.最后,消息是通過EventBus.getDefault.post(xx)發出的,一定是發送和接收出現問題.

推測該問題是由於主界面還未創建,用於接收的EventBus還未注冊,即發布者發了消息,但訂閱者還未產生(一般消息的處理邏輯是先注冊訂閱,后接收),這樣沒有收到消息當然無法響應操作.

了解到,EventBus是支持發送黏性事件的。

粘性事件?

何為黏性事件呢?簡單講,就是在發送事件之后再訂閱該事件也能收到該事件。Android中就有這樣的實例,也就是Sticky Broadcast,即粘性廣播。正常情況下如果發送者發送了某個廣播,而接收者在這個廣播發送后才注冊自己的Receiver,這時接收者便無法接收到 剛才的廣播,為此Android引入了StickyBroadcast,在廣播發送結束后會保存剛剛發送的廣播(Intent),這樣當接收者注冊完 Receiver后就可以接收到剛才已經發布的廣播。這就使得我們可以預先處理一些事件,讓有消費者時再把這些事件投遞給消費者.

EventBus也提供了這樣的功能,有所不同是EventBus會存儲所有的Sticky事件,如果某個事件在不需要再存儲則需要手動進行移除。用戶通過Sticky的形式發布事件,而消費者也需要通過Sticky的形式進行注冊,當然這種注冊除了可以接收 Sticky事件之外和常規的注冊功能是一樣的,其他類型的事件也會被正常處理。

基本使用

發布和接收粘性事件一般有如下幾步:

1、粘性事件的發布:

EventBus.getDefault().postSticky("RECOGNIZE_SONG");

2、粘性事件的接收

@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void receiveSoundRecongnizedmsg(String insType) {
        if ("RECOGNIZE_SONG".equals(insType)) {
            soundRecognizeCtrl();
        }
    }

剩下的操作就和普通事件一樣注冊和反注冊即可.

手動獲取和移除粘性事件(Getting and Removing sticky Events manually)

正如你之前看到的,最近發布的粘性事件在其新訂閱者注冊后將會自動傳遞給新訂閱者。但有時可能更方便手動檢查粘性事件。有時我們也需要移除粘性事件,以免它在傳遞下去。

MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
if(stickyEvent != null) {
    EventBus.getDefault().removeStickyEvent(stickyEvent);
  //TODO
}

removeStickyEvent 會返回之前持有的粘性事件。

於是,

MessageEvent stickyEvent = EventBus.getDefault().removeStickyEvent(MessageEvent.class);
if(stickyEvent != null) {
  //TODO
}

使用場景

我們要把一個Event發送到一個還沒有初始化的Activity/Fragment,即尚未訂閱事件。那么如果只是簡單的post一個事件,那么是無法收到的,這時候,你需要用到粘性事件,它可以幫你解決這類問題. 

小結

對於EventBus3.0來說,我還只是知道如何簡單的使用,是知其然,不知其所以然,它是一個比較強大的事件總線庫,后續會看下源碼,慢慢分析一下,消息是如何發送和接收的.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM