EventBus使用及解析

在我們剛學(xué)Android不久,就會學(xué)到用接口回調(diào)來異步通知事件。寫起來也算順手,但是接口回調(diào)需要不斷地設(shè)置listener,耦合性較大,當(dāng)項(xiàng)目越來越復(fù)雜,接口回調(diào)的傳值會形成一張錯(cuò)綜復(fù)雜的網(wǎng),有這樣使用經(jīng)歷的人就會深有感觸。于是,就可以使用EventBus的事件傳遞方法,在發(fā)送著和接收者完全解耦,傳遞接收范圍廣,接下來就學(xué)習(xí)怎樣使用Eventbus。

事件產(chǎn)生過程

流程示意圖

EventBus的三要素

Event:事件,可以是任意類型的對象。
Subscriber:事件訂閱者,在EventBus3.0之前消息處理的方法只能限定于onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,他們分別代表四種線程模型。而在EventBus3.0之后,事件處理的方法可以隨便取名,但是需要添加一個(gè)注解@Subscribe,并且要指定線程模型(默認(rèn)為POSTING)。
Publisher:事件發(fā)布者,可以在任意線程任意位置發(fā)送事件,直接調(diào)用EventBus的post(Object)方法??梢宰约簩?shí)例化EventBus對象,但一般使用EventBus.getDefault()就好了,根據(jù)post函數(shù)參數(shù)的類型,會自動調(diào)用訂閱相應(yīng)類型事件的函數(shù)。

使用步驟

引入庫

    implementation 'org.greenrobot:eventbus:3.0.0'

這里可以看到EventBus.getDefault()內(nèi)部調(diào)用的是懶漢式的單例獲取Eventbus對象方法。

    /** Convenience singleton for apps using a process-wide EventBus instance. */
    public static EventBus getDefault() {
        if (defaultInstance == null) {
            synchronized (EventBus.class) {
                if (defaultInstance == null) {
                    defaultInstance = new EventBus();
                }
            }
        }
        return defaultInstance;
    }

創(chuàng)建發(fā)送的實(shí)體類,根據(jù)發(fā)送者的實(shí)體類和接收者的實(shí)體類相匹配來看是否接收事件。

public class PostMsg {
    private int num;
    private String title;

    public PostMsg(int num, String title) {
        this.num = num;
        this.title = title;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

在任意需要發(fā)送事件的地方發(fā)送消息,對,發(fā)送就是這么簡單:

EventBus.getDefault().post(new PostMsg(100,"這里是標(biāo)題"));

接收消息的地方需要在onCreate()方法中進(jìn)行注冊

        EventBus.getDefault().post(this);

在onDestroy()方法中取消注冊(避免內(nèi)存泄漏)

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

接收消息

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(PostMsg postMsg){
        Toast.makeText(getApplicationContext(),postMsg.getNum() + "  " + postMsg.getTitle(),Toast.LENGTH_LONG).show();
    }

線程模式

public enum ThreadMode {

    POSTING,

    MAIN,

    BACKGROUND,

    ASYNC
}

POSTING:訂閱者方法將在發(fā)布事件所在的線程中被調(diào)用。是默認(rèn)的線程模式,該模式不會切換線程,意味著最少的性能開銷。可能會發(fā)生下主線程。
MAIN:訂閱者方法將在主線程中被調(diào)用。
BACKGROUND:訂閱者方法將在后臺線程中被調(diào)用。如果發(fā)布事件的線程不是主線程,那么訂閱者方法將直接在該線程中被調(diào)用。如果發(fā)布事件的線程是主線程,那么將使用一個(gè)單獨(dú)的后臺線程
ASYNC:訂閱者方法將在一個(gè)單獨(dú)的線程中被調(diào)用,該模式可用來執(zhí)行耗時(shí)操作。

粘性事件

當(dāng)有需求需要發(fā)送消息,所有注冊過的Activity都能收到。但是此時(shí)只有一部分Activity創(chuàng)建了,那么此時(shí)發(fā)出消息,未創(chuàng)建的Activity就接收不到消息。粘性事件就解決了該問題。通過 postSticky 發(fā)送粘性事件,這個(gè)事件不會只被消費(fèi)一次就消失,而是一直存在系統(tǒng)中,直到被 removeStickyEvent 刪除掉。

發(fā)布粘性事件

EventBus.getDefault().postSticky(new PostMsg(100,"這里是標(biāo)題"));

接收粘性事件

    @Subscribe(sticky = true)
    public void onEventMainThread(PostMsg postMsg){

    }

移除指定粘性事件

        //移除某種類型粘性事件
        EventBus.getDefault().removeStickyEvent(ThreadMode.xxx);
        //移除某種對象粘性事件
        EventBus.getDefault().removeStickyEvent(object);
         //移除所有粘性事件
        EventBus.getDefault().removeAllStickyEvents();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容