EventBus是一款針對Android優化的釋出/訂閱事件匯流排。可以替代廣播、startActivityForResult、Handler、非同步回撥等來實現各元件間、元件與後臺執行緒間的通訊。它的優點是開銷小,程式碼更優雅,以及將傳送者和接收者解耦。
通常我們在使用EventBus的時候都是直接需要接收通訊的Activity/Fragment中通過EventBus.getDefault().register(this)訂閱事件,在需要發起通訊的邏輯直接呼叫EventBus.getDefault().post(Object event)來發布事件。但是要是一個專案中有很多地方都使用EventBus來通訊,比如重新登入後更新各個頁面的登入狀態,或者是接收到通知更新訊息提示等,都這樣直接使用的話程式碼重複率很高,並且呢,如果以後升級或者更換EventBus時,各個地方都要修改,這就比較麻煩了。因此我一般是將EventBus的釋出和訂閱封裝到BaseActivity/BaseFragment中。
接下來我們開始封裝之路:
1、添依賴
在Gradle中新增EventBus依賴:
compile 'org.greenrobot:eventbus:3.0.0'
複製程式碼
2、考慮基類中進行繫結
2.1、我們應該這樣想,如果在BaseActivity或BaseFragment中定義一抽象方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (isRegisterEventBus()) {
EventBusUtil.register(this);
}
}
/**
* 是否註冊事件分發
*
* @return true繫結EventBus事件分發,預設不繫結,子類需要繫結的話複寫此方法返回true.
*/
protected boolean isRegisterEventBus() {
return false;
}
@Override
public void onDestroy() {
super.onDestroy();
if (isRegisterEventBus()) {
EventBusUtil.unregister(this);
}
}
複製程式碼
如上,那豈不所有Base類的子類都需要去實現 isRegisterEventBus 方法,來返回是否繫結EventBus,那對於不繫結EventBus的類來說不是很累贅麻煩嘛。
2.2、使用註解
現在想想,使用註解是不是會方便一些呢?
先建立一註解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindEventBus {
}
複製程式碼
現在,只要被此註解修飾的類,就表示與EventBus繫結。那麼在Base類中:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 若使用BindEventBus註解,則繫結EventBus
if(this.getClass().isAnnotationPresent(BindEventBus.class)){
EventBusUtils.register(this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 若使用BindEventBus註解,則解繫結EventBus
if(this.getClass().isAnnotationPresent(BindEventBus.class)){
EventBusUtils.unregister(this);
}
}
複製程式碼
這樣方便多了。
3、對Event的封裝
public class Event<T> {
private int code;
private T data;
public Event(int code, T data) {
this.code = code;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
複製程式碼
Event傳入一個泛型T,這裡T是具體的事件類,Event是將具體事件與對應業務code進行封裝。
再來看下code
public class EventCode {
public static final int A = 0x111111;
public static final int B = 0x222222;
public static final int C = 0x333333;
public static final int D = 0x444444;
}
複製程式碼
這裡可以定義一些業務相關的code,如登入、支付等等。以便將來對其分類處理。
4、處理類
public class EventBusUtils {
/**
* 繫結 接受者
* @param subscriber
*/
public static void register(Object subscriber) {
EventBus.getDefault().register(subscriber);
}
/**
* 解繫結
* @param subscriber
*/
public static void unregister(Object subscriber){
EventBus.getDefault().unregister(subscriber);
}
/**
* 傳送訊息(事件)
* @param event
*/
public static void sendEvent(Event event){
EventBus.getDefault().post(event);
}
/**
* 傳送 粘性 事件
*
* 粘性事件,在註冊之前便把事件發生出去,等到註冊之後便會收到最近傳送的粘性事件(必須匹配)
* 注意:只會接收到最近傳送的一次粘性事件,之前的會接受不到。
* @param event
*/
public static void sendStickyEvent(Event event){
EventBus.getDefault().postSticky(event);
}
}
複製程式碼
前兩個方法是註冊也解註冊,已經在Base類中用到了。
sendEvent和sendStickyEvent就是具體的傳送訊息的方法,注意這裡傳送的是Event。
5、使用
5.1、Activity或Fragment中
@BindEventBus
public class ABCActivity extends BaseActivity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void handleEvent(Event<ABC> event){
// do something
}
}
複製程式碼
繼承Base類,使用BindEventBus註解;
建立接收和處理事件的方法。
5.2、傳送訊息
Event<ABC> event=new Event<>(0,new ABC());
EventBusUtils.sendEvent(event);
複製程式碼
這樣就ok了。各位大神有好的建議就告訴我哦。
更多精彩內容,關注我的微信公眾號——Android機動車。