之前每一個頁面與每一個頁面業務邏輯傳遞讓你不知所措,一個又一個接口回調,讓你暈頭轉向,一個又一個參數讓你混亂不堪。EventBus一個耦合度低的讓你懼怕的框架。java
EventBus是一個消息總線,以觀察者模式實現,用於簡化程序的組件,能夠輕易切換線程,實現各組件之間的刷新通知,以及參數的傳遞。EventBus3.0跟以前版本的區別框架
是介入了annotation @Subscribe,取代了之前約定命名的方式。異步
它代替了廣播,startActivityforResult,Handle,異步回調等,來實現各個組件間,線程間的通信,優勢是開銷小,代碼更優雅,以及將發送者與接受者解耦。ide
咱們今天直接看EventBus封裝過程。post
EventBus的訂閱,接收,發送,咱們都放在基類BaseActivity/BaseFragment中完成(EventBus.getDefault().register(this)
訂閱事件,發起通訊的邏輯直接調用EventBus.getDefault().post(Object event)
來發布事件)。this
在Gradle中添加EventBus
依賴:線程
compile 'org.greenrobot:eventbus:3.0.0'
封裝一下EventBus
的訂閱、取消訂閱、發佈等方法:code
public class EventBusUtil { public static void register(Object subscriber) { EventBus.getDefault().register(subscriber); } public static void unregister(Object subscriber) { EventBus.getDefault().unregister(subscriber); } public static void sendEvent(Event event) { EventBus.getDefault().post(event); } public static void sendStickyEvent(Event event) { EventBus.getDefault().postSticky(event); } // 其餘 }
在BaseActivity/BaseFragment
中的onCreate
和onDestroy
方法中訂閱和取消訂閱,這裏添加了一個isRegisterEventBus()
方法,默認返回false
,即不訂閱EventBus
,子類Activity/Fragment
若是須要訂閱的話複寫這個方法並返回true
便可。blog
@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); } }
定義事件Event
:接口
public class Event<T> { private int code; private T data; public Event(int code) { this.code = code; } 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; } }
經過泛型<T>
指定事件通訊過程當中的數據類型,code
爲事件碼,使用的時候給不一樣的事件類型指定不一樣的code
。
在BaseActivity\BaseFragment
中添加接收到EventBus
的方法:
/** * 是否註冊事件分發 * * @return true綁定EventBus事件分發,默認不綁定,子類須要綁定的話複寫此方法返回true. */ protected boolean isRegisterEventBus() { return false; } @Subscribe(threadMode = ThreadMode.MAIN) public void onEventBusCome(Event event) { if (event != null) { receiveEvent(event); } } @Subscribe(threadMode = ThreadMode.MAIN, sticky = true) public void onStickyEventBusCome(Event event) { if (event != null) { receiveStickyEvent(event); } } /** * 接收到分發到事件 * * @param event 事件 */ protected void receiveEvent(Event event) { } /** * 接受到分發的粘性事件 * * @param event 粘性事件 */ protected void receiveStickyEvent(Event event) { }
根據本身項目的需求,在訂閱了EventBus
的Activity/Fragment
中複寫receiveEvent(Event event)
或receiveStickyEvent(Event event)
來處理接收到事件後的邏輯。
這裏也能夠不用在BaseActivty/BaseFragment
中添加接受事件的方法(由於添加了事後不能肯定的子類的Event
泛型)。那麼就直接在訂閱的Activity/Fragment
中給接收事件的方法添加EventBus
對應的事件接受註解,並指定參數Event的泛型。
@Subscribe(threadMode = ThreadMode.MAIN) public void onEventReceived(Event<User> event) { if (event != null && event.getCode() == C.EventCode.C) { User user = event.getData(); } }
在給定Event
的code
的時候最好在常量池中定義一個類專門用來定義不一樣類型的EventBus
的code
,這樣在接收到EventBus
的地方能夠根據這些code
值來判斷Event
的來源。
public final class C { // EventBus Code public static final 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; // other more } }
使用示例:
在MainActivity
中複寫isRegisterEventBus()
並返回true
註冊EventBus
,複寫receiveEvent(Event event)
接收發布的事件。
@Override protected boolean isRegisterEventBus() { return true; } @Override protected void receiveEvent(Event event) { // 接受到Event後的相關邏輯 switch (event.getCode()) { case C.EventCode.A: Log.d("EventBus", "接收到A類型的Event"); break; case C.EventCode.B: Log.d("EventBus", "接收到B類型的Event"); break; case C.EventCode.C: Log.d("EventBus", "接收到B類型的Event,攜帶User"); User user = (User) event.getData(); break; case C.EventCode.D: Log.d("EventBus", "接收到D類型的Event,攜帶News"); News news = (News) event.getData(); break; } }
在receiveEvent(Event event)
根據對應的事件的code
,判斷通訊的數據來源和傳遞的數據類型,以完成對應的邏輯。
在InfoActivity
中發送事件,InfoActivity
只發送不須要接收Event
的話就不註冊,也不用複寫isRegisterEventBus()
和receiveEvent(Event event)
方法了。
public void sendEventA(View view) { EventBusUtil.sendEvent(new Event(C.EventCode.A)); } public void sendEventB(View view) { EventBusUtil.sendEvent(new Event(C.EventCode.B)); } public void sendEventC(View view) { Event<User> event = new Event<>(C.EventCode.C, new User()); EventBusUtil.sendEvent(event); } public void sendEventD(View view) { Event<News> event = new Event<>(C.EventCode.D, new News()); EventBusUtil.sendEvent(event); }
經過上面的方式,將EventBus
封裝到BaseActivity/BaseFragment
中,使得EventBus和項目解耦更加完全,同時在須要使用的子Activity/Fragment中只須要複寫isRegisterEventBus()
和receiveEvent(Event event)
便可,不用每一個地方都去訂閱和取消訂閱。而且給Event
給定code
和泛型可以很好的區分不一樣的事件來源和數據類型。