EventBus簡(jiǎn)單實(shí)用

簡(jiǎn)介

EventBus 是一款訂閱——發(fā)布模式為核心的開(kāi)源庫(kù) ,EventBus翻譯過(guò)來(lái)是事件總線的意思,一個(gè)個(gè)事件(event)發(fā)送到總線上,然后EventBus根據(jù)已注冊(cè)的訂閱者(subscribers)來(lái)匹配相應(yīng)的事件,進(jìn)而把事件傳遞給訂閱者,這個(gè)就是典型的觀察者模式
EventBus GitHub地址

對(duì)比近似功能

對(duì)比廣播,這個(gè)框架的封裝了,沒(méi)有那么重量級(jí)吧個(gè)人理解差距不大,handler ,startActivityForResult()等。并且這個(gè)也和廣播類(lèi)似有個(gè)粘性的概念

使用

1.在Android Studio中添加如下依賴(lài):

compile 'org.greenrobot:eventbus:3.0.0'

2.創(chuàng)建事件實(shí)體類(lèi),事件實(shí)體類(lèi),就是傳遞的事件,一個(gè)組件向另一個(gè)組件發(fā)送的信息可以?xún)?chǔ)存在一個(gè)類(lèi)中,該類(lèi)就是一個(gè)事件,會(huì)被EventBus發(fā)送給訂閱者 ,

如果你想發(fā)送字符串可以這樣設(shè)置你的messageEvent構(gòu)造 string類(lèi)型:

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

public class MessageEvent {

    private String message;

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

    public String getMessage(){
        return message;
    }
}

3.向EventBus注冊(cè),成為訂閱者以及解除注冊(cè)

EventBus.getDefault().register(this);

即可將當(dāng)前類(lèi)注冊(cè),成為訂閱者,即對(duì)應(yīng)觀察者模式的“觀察者”,一旦有事件發(fā)送過(guò)來(lái),該觀察者就會(huì)接收到匹配的事件。通常,在類(lèi)的初始化時(shí)便進(jìn)行注冊(cè),如果是Activity則在onCreate()方法內(nèi)進(jìn)行注冊(cè)。
當(dāng)訂閱者不再需要接受事件的時(shí)候,我們需要解除注冊(cè),釋放內(nèi)存:

EventBus.getDefault().unregister(this);

4.聲明訂閱方法
觀察者模式,觀察者有著一個(gè)update()方法,在接收到事件的時(shí)候會(huì)調(diào)用該update()方法,這個(gè)方法就是一個(gè)訂閱方法。在EventBus 3.0中,聲明一個(gè)訂閱方法需要用到@Subscribe注解,因此在訂閱者類(lèi)中添加一個(gè)有著@Subscribe注解的方法即可,方法名字可自定義,而且必須是public權(quán)限,其方法參數(shù)有且只能有一個(gè),另外類(lèi)型必須為第一步定義好的事件類(lèi)型(比如上面的MessageEvent),如下所示

@Subscribe 
public void onEvent(MessageEvent event) {
    /* Do something */
}

5.發(fā)送事件
與觀察者模式對(duì)應(yīng)的,當(dāng)有事件發(fā)生,需要通知觀察者的時(shí)候,被觀察者會(huì)調(diào)用notifyObservers()方法來(lái)通知所有已經(jīng)注冊(cè)的觀察者,在EventBus中,對(duì)觀察者模式底層進(jìn)行了封裝,我們只需要調(diào)用以下代碼就能把事件發(fā)送出去:

EventBus.getDefault().post(EventType eventType);

上面的5個(gè)步驟就完成了EventBus 訂閱發(fā)布了,可能大家比較陌生的就是@Subscribe注解

@Subscribe注解

訂閱方法,添加了@Subscribe注解,直接看他的代碼。按住點(diǎn)進(jìn)去

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    ThreadMode threadMode() default ThreadMode.POSTING;

    /**
     * If true, delivers the most recent sticky event (posted with
     * {@link EventBus#postSticky(Object)}) to this subscriber (if event available).
     */
    boolean sticky() default false;

    /** Subscriber priority to influence the order of event delivery.
     * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before
     * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of
     * delivery among subscribers with different {@link ThreadMode}s! */
    int priority() default 0;
}

內(nèi)部有三個(gè)成員,分別是threadMode、sticky、priority。

threadMode代表訂閱方法所運(yùn)行的線程,
public enum ThreadMode {
    
    POSTING,
    
    MAIN,
    
    BACKGROUND,

    ASYNC
}

POSTING:表示訂閱方法運(yùn)行在發(fā)送事件的線程
MAIN:表示訂閱方法運(yùn)行在UI線程,由于UI線程不能阻塞,因此當(dāng)使用MAIN的時(shí)候,訂閱方法不應(yīng)該耗時(shí)過(guò)長(zhǎng)
BACKGROUND:表示訂閱方法運(yùn)行在后臺(tái)線程,如果發(fā)送的事件線程不是UI線程,那么就使用該線程;如果發(fā)送事件的線程是UI線程,那么新建一個(gè)后臺(tái)線程來(lái)調(diào)用訂閱方法
ASYNC:訂閱方法與發(fā)送事件始終不在同一個(gè)線程,即訂閱方法始終會(huì)使用新的線程來(lái)運(yùn)行。
一般都是下面的方式,因?yàn)槲覀円话愣际且耈I要回到主線程:

/訂閱方法,當(dāng)接收到事件的時(shí)候,會(huì)調(diào)用該方法
    @Subscribe(threadMode = ThreadMode.MAIN)
sticky代表是否是粘性事件,下面再說(shuō)
priority代表優(yōu)先級(jí)。設(shè)置該優(yōu)先級(jí)的目的是,當(dāng)一個(gè)事件有多個(gè)訂閱者的時(shí)候,優(yōu)先級(jí)高的會(huì)優(yōu)先接收到事件。給這個(gè)三個(gè)成員賦不同的值,能使得訂閱方法有著不同的效果。

sticky解釋

關(guān)于粘性事件,可以參考Android的廣播機(jī)制,其中有一個(gè)粘性廣播,粘性廣播的意思是:該廣播發(fā)送后,會(huì)保存在內(nèi)存中,如果后來(lái)有注冊(cè)的Receiver與之匹配,那么該Receiver便會(huì)接收到該廣播。那么粘性事件同理,在注冊(cè)之前便把事件發(fā)生出去,等到注冊(cè)之后便會(huì)收到最近發(fā)送的粘性事件(必須匹配)。注意:只會(huì)接收到最近發(fā)送的一次粘性事件,之前的會(huì)接受不到

如果發(fā)送了3個(gè)sticky事件,同一個(gè)訂閱者只會(huì)收到最后一個(gè)!!!!切記,可以聯(lián)系觀察者模式記憶,觀察者是做出三次改變 ,會(huì)響應(yīng)3次,但是這里不會(huì),只會(huì)執(zhí)行最后一次!!!!

結(jié)果親測(cè),版本有限就不貼出了。只會(huì)接受到最后發(fā)送的粘性事件,在此之前的事件都接收不到!!!

sticky在實(shí)際項(xiàng)目中用到的場(chǎng)景

我們公司項(xiàng)目做的基金模塊頁(yè)面就是頂部有多個(gè)tab 沒(méi)個(gè)tab 的頭部都有一個(gè)基金購(gòu)買(mǎi)風(fēng)險(xiǎn)的提示,用戶(hù)在這6個(gè)tab 每個(gè)頁(yè)面是不同的,但是都存在這個(gè),現(xiàn)在需求就是我點(diǎn)擊任意頁(yè)面的提示 表明我知道這個(gè)事情了,然后在其他5個(gè)頁(yè)面都不顯示了,這個(gè)時(shí)候就用的是sticky發(fā)送事件

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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