這麼美好的週六,在加班中度過了,十一點了,把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對象。但是需要注意在某些情況下,我們需要使用黏性事件,具體的場景在博客中有舉例。