Android最火的框架系列(八)EventBus

        這麼美好的週六,在加班中度過了,十一點了,把EventBus總結一下。EventBus是一套可靈活使用的Android組件間通信框架。不僅可以便捷的傳遞Java變量,也可以傳遞複雜的Java對象。EventBus的使用也比較簡單,消息發佈者只需要在合適的時機發送消息,消息接收者只需要通過註冊,處理和註銷三個步驟,即可完成對消息的接收和處理。

一.觀察者模式

        首先,在說EventBus之前,我們先了解一下觀察者模式,因爲EventBus是基於觀察者模式的。什麼是觀察者模式?簡單來說,它定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。Android中很多地方都用到了觀察者模式,例如:TextWatcher,OnClickListener,廣播,Adapter等。

二.EventBus導入

        這是EventBus的GitHub地址:https://github.com/greenrobot/EventBus.以下是截止到我寫這篇博客的版本號:

implementation 'org.greenrobot:eventbus:3.1.1'

三.EventBus的簡單使用

        前面說過,EventBus的使用比較簡單。發佈者和接收者各自做好自己的事情即可。前面也簡單提起過,發佈者只需要發佈事件,而接收者也只需要註冊,處理和註銷三個步驟。

1.發佈者發佈事件

        發佈者發佈事件,只需要一行代碼。我們只需要在合適的時機去觸發事件的發送,例如:點擊Button或者在Activity的某個生命週期等等,如下是代碼:

EventBus.getDefault().post(event)

2.接受者接收事件

        接收者接收事件,需要三個步驟:註冊,處理,註銷。很容易理解,我們需要註冊EventBus,這樣我們才能接收到事件。接收到事件後,我們需要處理事件。處理完事件後,在合適的時機註銷EventBus。

(1)註冊

        在接收事件之前,我們首先要註冊EventBus,一般我們放在Activity的onCreate中:

EventBus.getDefault().register(this);

(2)處理

        處理的方法,需要@Subscribe的註解,我們在方法裏面針對event進行一系列的操作,例如更新UI:

@Subscribe(threadMode = ThreadMode.MAIN)

public void handleMessage(UserInfoEvent event) {

    //針對event進行處理

}

(3)註銷

         註冊和註銷,在Android中永遠是成對出現的(當然,你也可以不成對出現,如果你想出現線程或者內存等問題的話)。因此,在處理完事件後,我們要在合適的時機註銷EventBus,我們一般放在Activity的onDestroy中:

EventBus.getDefault().unregister(this);

四.黏性事件

        什麼是黏性事件呢?簡單講,在發送事件之後再訂閱該事件也能收到該事件。一般情況下,消息接受都是先註冊訂閱,然後才能接受。就比如訂報紙,你沒訂報紙,送報紙的人不會把報紙送到你手上。但是,假如你正好在路上遇到送報紙的,你說我要訂報紙,那你是不是可以當時收到報紙了,以後也可以收到報紙。考慮如下兩種場景:

        (1)activity1是app啓動的首頁,它是一個接收者,activity2是發佈者,我們從activity1跳轉到activity2,然後在activity2中發佈事件。

        (2)接着(1)的場景,我們有一個activity3,它從未被創建過,我們也想讓它作爲一個接收者,接收activity2發佈的事件。

        我們分析一下上面的兩個場景:

        第一種情況,由於activity1是app啓動的首頁,也就是被創建過,那麼它的註冊是有效的,他可以正常接收到activity2發佈的事件。

        第二種情況,由於activity3從未被啓動過,它的註冊是無效的,他不能正常的接收activity2發佈的事件。那如何讓activity3在創建的時候也能接收到activity2發佈的事件呢?我們可以使用eventbus的黏性事件。

1.發佈者發佈事件

        發佈者發佈事件,仍然只需要一行代碼。跟普通事件不一樣的是,多了一個Sticky,如下是代碼        

EventBus.getDefault().postSticky(event)

2.接受者接收事件

        註冊和註銷的方法和位置不變,不同的是,處理事件的方法。需要在@Subscribe註解中,增加sticky = true,標誌着我們的事件是黏性事件:

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)

public void handleMessage(UserInfoEvent event) {

    //處理event

}

        因此,當我們要把一個Event發送到一個還沒有初始化的Activity/Fragment,如果只是簡單的post一個事件,那麼是無法收到的,我們需要使用黏性事件。

五.代碼

1.Event示例:

package com.example.tuduzhao.tudueventbusdemo;

/**
 * Created by Tudu.Zhao
 * on 2019/8/15
 **/
public class UserInfoEvent {
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2.發送事件示例:

btn = findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                UserInfoEvent event = new UserInfoEvent();
                event.setId("20190815");
                event.setName("tudu.zhao");
                EventBus.getDefault().postSticky(event);
            }
        });

3.處理事件示例:

    @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
    public void handleMessage(UserInfoEvent event) {
        String name = event.getName();
        String id = event.getId();
        tv1.setText(id);
        tv2.setText(name);
    }

4.完整代碼:

https://github.com/hearttudu/TuDuEventBusDemo

        最後,總結一下。EventBus的使用比較簡單,可以便捷的實現Android組件間的通信,可以發送Java變量或者複雜的Java對象。但是需要注意在某些情況下,我們需要使用黏性事件,具體的場景在博客中有舉例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章