EventBus的使用

EventBus用了好久了,一直沒有整理一下。
我們往簡單裏說,EventBus的出現,讓我們在大部分情況下,不需要使用broadcast來在不同的activity,fragment,甚至是adapter(我知道你們經常糾結adapter和activity的交互!)之間交互了。
當然,如果你要獲取系統廣播什麼的,還是需要broadcast的。
而且EventBus的回調很豐富,你甚至可以指定你的回調運行在哪個線程裏(這個很方便有木有)

我們舉一個例子來說明一下:
廢代碼我們就不寫了,省得大家看起來亂。
我們來舉一個從adapter到activity傳值的例子。
首先我們有一個adapter,叫ListAdapter,我們打算在點擊ListAdapter中某個item的按鈕時,發送一個消息到MainActivity,MainActivity接收一個消息後,彈出一個toast提示框。
跟動態廣播一樣,首先我們要爲每一個廣播指定類型,所以我們寫了一個Event類:

public class Event<T> {
    private EventType eventType;
    private T message;

    public Event(EventType eventType) {
        this.eventType = eventType;
    }

    public Event(EventType eventType, T message) {
        this.eventType = eventType;
        this.message = message;
    }

    public EventType getEventType() {
        return eventType;
    }

    public void setEventType(EventType eventType) {
        this.eventType = eventType;
    }

    public T getMessage() {
        return message;
    }

    public void setMessage(T message) {
        this.message = message;
    }
}

以及定義了幾種事件:

public enum EventType {
    START_MINING, 
    ENTER_GAME_TAB,   
}

定義完了後,首先我們要在MainActivity的onCreate方法中註冊一個EventBus:

EventBus.getDefault().register(this);

並在onDestroy方法中反註冊它:

EventBus.getDefault().unregister(this);

這樣,MainActivity就可以接收到EventBus的消息了。
然後我們要在ListAdapter裏面發送消息:

        holder.image_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            //這裏,我們在按鈕的點擊事件裏發送消息
                EventBus.getDefault().post(
                        new Event(EventType.START_MINING, getItem(pos).mountainLevel));
            }
        });

梳理一下,現在我們完成了消息發送和消息接收方的註冊了。那對比廣播,我們還需要一個接受消息的地方。
其實很簡單,我們回到MainActivity,寫一個方法:

    public void onEventMainThread(Event event) {

        String msg = "onEventMainThread收到了消息:" + event.getMessage();
        Toast.makeText(mContext, msg, Toast.LENGTH_LONG).show();
    }

然後這個方法會自動接收MainActivity收到的消息。
是不是很奇怪,爲什麼我隨便定義了一個方法,既沒有指定這個方法接收消息,而且這個方法也不是我重寫的?(比如繼承了EventBus類,然後重寫它的接收方法)
最初我也很奇怪,所以我做了一個實驗,我把onEventMainThread改名了,改成offEventMainThread,結果居然運行報錯,大致意思是說,我在MainActivity中註冊了EventBus,但是我沒有指定接收方法!
又找了些資料研究了下,EventBus應該是註冊了之後,就會在這個類MainActivity裝載的時候,自動掃描是否有接收方法,如果沒有就直接拋出異常

除了onEventMainThread,EventBus還有別的接收方法,我直接飲用了別的資料:

EventBus還有另外有個不同的函數,他們分別是:
1、onEvent
2、onEventMainThread
3、onEventBackgroundThread
4、onEventAsync
這四種訂閱函數都是使用onEvent開頭的,它們的功能稍有不同,在介紹不同之前先介紹兩個概念:
告知觀察者事件發生時通過EventBus.post函數實現,這個過程叫做事件的發佈,觀察者被告知事件發生叫做事件的接收,是通過下面的訂閱函數實現的。
onEvent:如果使用onEvent作爲訂閱函數,那麼該事件在哪個線程發佈出來的,onEvent就會在這個線程中運行,也就是說發佈事件和接收事件線程在同一個線程。使用這個方法時,在onEvent方法中不能執行耗時操作,如果執行耗時操作容易導致事件分發延遲。
onEventMainThread:如果使用onEventMainThread作爲訂閱函數,那麼不論事件是在哪個線程中發佈出來的,onEventMainThread都會在UI線程中執行,接收事件就會在UI線程中運行,這個在Android中是非常有用的,因爲在Android中只能在UI線程中跟新UI,所以在onEvnetMainThread方法中是不能執行耗時操作的。
onEventBackground:如果使用onEventBackgrond作爲訂閱函數,那麼如果事件是在UI線程中發佈出來的,那麼onEventBackground就會在子線程中運行,如果事件本來就是子線程中發佈出來的,那麼onEventBackground函數直接在該子線程中執行。
onEventAsync:使用這個函數作爲訂閱函數,那麼無論事件在哪個線程發佈,都會創建新的子線程在執行onEventAsync.

發佈了46 篇原創文章 · 獲贊 55 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章