EventBus基本使用簡介

一、背景介紹
在編程過程中,當我們想通知其他組件某些事情發生時,我們通常使用觀察者模式,正是因爲觀察者模式非常常見,所以在jdk1.5中已經幫助我們實現了觀察者模式,我們只需要簡單的繼承一些類就可以快速使用觀察者模式,在Android中也有一個類似功能的開源庫EventBus。 此篇幅主要講述EventBus是什麼?EventBus可以幫助我們幹些什麼?還有EventBus是怎樣調用的?下一篇幅將會對EventBus的源碼進行解讀,分析EventBus框架結構,工作原理等,敬請關注。

二、EventBus簡介
對於Android開發人員來講,跨線程通信,多個Activity通信,服務和UI通信,組件之間的通信等,並不陌生,Android系統給我們提供了很多便捷的方法,例如廣播,Handler,方法回調等。在GitHut上有這麼一個開源庫EventBus,他很好的解決了以上所述場景的通信,並提供了簡化,易懂,低耦合的架構API。

  1. 什麼是EventBus
    EventBus其實是利用了這麼一個概念,以發佈者和訂閱者的角色,描述和處理事件的傳遞,事件傳遞之間帶有事件屬性(即數據)。而且這個角色是可以進行對調的,一個發佈者可以去發佈事件也可以接受事件,一個訂閱者可以訂閱多個事件也可以發佈事件,這樣就形成了事件池的事件分發機制,所有發佈者發佈的事件被存儲在對應EventBus的事件池中,所有訂閱者根據自己的需要往事件池裏註冊要訂閱的事件,當事件池中有事件進來時,EventBus會根據事件分發原則把事件分發到訂閱者去處理。
  2. EventBus能做什麼,怎麼調用
    首先EventBus是一個開源框架,此框架主要是建立事件分發和訂閱的。用來簡化應用組件之間的通信,替代傳統通信模式:廣播,Handler,方法回調,而生的一個輕量級的通信架構,使用者只需要進行註冊,訂閱,發佈,取消訂閱,這幾個簡單的操作既可以完成不同組件之間的通信交流和數據傳輸。在實際應用開發中,我們總是希望把耗時複雜的工作交給service去處理,在UI組件中只關心結果的展示和用戶的交互。在EventBus沒出來前,我們可能想到最多的方法可能就是廣播,Handler線程通信等等方法來解決,但是無可否認這些傳統的處理方法有時候太過於繁瑣,而EventBus能更好,更簡潔地幫我們解決這些繁瑣的問題。至於EventBus怎麼調用?下面我們由Demo來講解。

Demo講解

例如我們要做一個計時器,希望服務端每一秒通知一下UI端去更新時間信息這麼一個需要求。在傳統模式下,我們可能需要綁定服務,在服務中調用UI組件進行更新視圖,又或者建立回調方法進行通知變更。那麼在EventBus中,我們是怎樣處理的呢?

  1. 引入EventBus開源庫
  2. 註冊到EventBus
  3. 訂閱事件
  4. 發佈事件
  5. 反註冊EventBus

下面結合Demo的代碼進行分析:
先在gradle中添加依賴:

compile 'org.greenrobot:eventbus:3.0.0'

接着看看核心代碼:

public class MainActivity extends Activity {
    private TextView time;
    private Intent tS;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        time = (TextView) findViewById(R.id.time);
        EventBus.getDefault().register(this);
        tS = new Intent(this, TimeService.class);
        startService(tS);
    }
    public void onEventMainThread(TimeEvent event) {
        int h = 0, m = 0, s = 0;
        int t = event.getTime();
        if (t >= 86400) {
            time.setText("24:00:00+");
        } else {
            if (t >= 3600) {
                h = t / 3600;
                t = t % 3600;
            }
            if (t >= 60) {
                m = t / 60;
                t = t % 60;
            }
            s = t;
            time.setText(h + ":" + m + ":" + s);
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        stopService(tS);
    }
}
  1. 要接收事件,那麼先要有訂閱者,在此示例中訂閱者就是主Activity本身,我們要把它註冊到EventBus中
EventBus.getDefault().register(this);

通過以上這麼一行代碼,我們就完成了訂閱者的註冊,這裏默認註冊到默認的EventBus當中,也可以通過其他API建立不同的EventBus對象,每個EventBus對象的事件是互不干擾分發的

  1. 完成註冊後,我們要進行事件的訂閱,要有事件的訂閱,就必須有對應Type的事件,也就是常說的EventModel
public class TimeEvent {
    private int time = 0;

    public int getTime(){
       return time;
    }

    public void setTime(int t){
        time = t;
    }
}

由於我們是要做一個計時器,那麼事件我們就定義爲一個TimeEvent,裏面返回秒數信息就可以了。訂閱事件其實就是在訂閱者中增加以OnEvent開頭的public類型的函數方法:

public void onEventMainThread(TimeEvent event) {
        int h = 0, m = 0, s = 0;
        int t = event.getTime();
        if (t >= 86400) {
            time.setText("24:00:00+");
        } else {
            if (t >= 3600) {
                h = t / 3600;
                t = t % 3600;
            }
            if (t >= 60) {
                m = t / 60;
                t = t % 60;
            }
            s = t;
            time.setText(h + ":" + m + ":" + s);
        }
    }

對應的參數是唯一的時間類型對象,OnEventXXX有幾種時間Mode,分別對應PostThread,MainThread,BackgroundThread,Async根據字面意思也很好理解他們分別在那個線程進行工作處理的,默認爲PostThread模式,以上我們接受到TimeEvent時,做了一件事件就是在主線程中根據返回的event中的秒數,進行更新UI組件TextView,進行顯示。
3.有了訂閱者,有了訂閱時間,我們就需要一個發佈者和發佈事件的流程,我們完成計數的操作是早Service中完成的。

public class TimeService extends Service {
    private Thread mTime;
    private TimeEvent mTimeEvent;
    public TimeService() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override
    public void onCreate() {
        super.onCreate();
        mTimeEvent = new TimeEvent();
        mTime = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    mTimeEvent.setTime(mTimeEvent.getTime() + 1);
                    EventBus.getDefault().post(mTimeEvent);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        mTime.start();
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        mTime.stop();
        mTime.destroy();
        mTime = null;
    }
}

服務開啓時,我們啓了一個線程進行每秒的計數,並通過:

EventBus.getDefault().post(mTimeEvent);

把事件結果發佈到EventBus中分發處理,EventBus會根據已有的訂閱者,調度對應的OnEventXX通過訂閱者事件結果。
4.當我們一旦不需要訂閱了,我們可以通過反註冊取消

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