背景
在Android
開發中數據傳遞的方式有不少種,常見的有java
Intent
在頁面間傳遞數據Handler
刷新UIBroadcast
傳遞消息
系統提供的API
在使用上會有些複雜。
舉個示例:Handler發送數據並刷新UI
git
Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: // 完成主界面更新,拿到數據 String data = (String) msg.obj; textView.setText(data); break; default: break; } } }; private void getDataFromNet() { new Thread(new Runnable() { @Override public void run() { //耗時操做,完成以後發送消息給Handler,完成UI更新; mHandler.sendEmptyMessage(0); //須要數據傳遞,用下面方法; Message msg = new Message(); //能夠是基本類型,能夠是對象,能夠是List、map等; msg.obj = "網絡數據"; mHandler.sendMessage(msg); } }).start(); }
下面是EventBus
簡單使用的僞代碼
:github
// 註冊 EventBus.getDefault().register(this); // 註銷 EventBus.getDefault().unregister(this); // 發送 MessageEvent 事件 EventBus.getDefault().post(new MessageEvent("Hello everyone!")); // 接收 MessageEvent 事件 @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MessageEvent event) { Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show(); }
固然,EventBus
的出現不是爲了取代系統API
,只是給咱們提供了更多的選擇。
在系統API
能輕鬆實現的狀況下,就不必引入EventBus
了,雖然它只有60k
。web
接下來咱們須要對EventBus
進行更進一步的瞭解,才能更好地使用。網絡
定義
EventBus
是一個事件發佈/訂閱輕量級框架。相關的發佈訂閱可參考:發佈訂閱-維基百科。
關於觀察者模式和發佈訂閱模式的談論,可查看知乎這篇文章。
EventBus
的事件發佈者不會將事件直接發給訂閱者,而是將發佈的事件分爲不一樣的類型,訂閱者能夠選擇只感興趣的事件訂閱。
使用過EventBus
的朋友回憶一下,確實是如此。沒使用過EventBus
的朋友能夠耐心往下看。ide
它有如下優勢:svg
- 可以簡化組件間的通訊
- 有效地將事件發送者和訂閱者解耦
- 能避免複雜的依賴性和生命週期問題
- 在
Fragment,Activity,Service, 後臺線程
之間傳遞數據,性能更好。
EventBus
能夠代替Android
傳統的Intent,Handler,Broadcast 或接口函數
,函數
基本使用
使用步驟分爲下面幾步:post
- 引入依賴
- 定義事件對象
- 事件訂閱和解除訂閱
- 發送事件
引入依賴
implementation 'org.greenrobot:eventbus:3.1.1'
定義事件對象
public class MessageEvent { public final String message; public MessageEvent(String message) { this.message = message; } }
事件訂閱
事件不可重複訂閱,通常咱們在
onCreate
或者onStart
方法中訂閱
@Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); }
解除事件訂閱
事件不可重複解除訂閱,通常咱們在
onStop
或者onDestory
方法中解除訂閱
@Override public void onStop() { EventBus.getDefault().unregister(this); super.onStop(); }
發送事件
- 普通事件:須要先註冊事件才能接收到已發出的事件
- 粘性事件:事件不須要提早註冊也能接收到。
好比:A
頁面跳轉 B
頁面傳遞參數hello
,
若是傳遞參數時使用粘性事件,也就是在A
頁面發送數據,在B
頁面註冊事件。且接收粘性事件,那麼B
能夠接收到參數hello
若是傳遞參數時使用普通事件,那麼B
能夠接收不到參數hello
。由於普通參數須要註冊才能收到消息。
接下來看普通事件和粘性事件的使用。
普通事件
EventBus.getDefault().post(new MessageEvent("Hello everyone!")); // 在主線程展現 Toast 結果 @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MessageEvent event) { Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show(); }
粘性事件
EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!")); // 在主線程刷新 UI @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) public void onEvent(MessageEvent event) { textField.setText(event.message); } // 移除粘性事件 MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class); // Better check that an event was actually posted before if(stickyEvent != null) { // 移除某個事件 EventBus.getDefault().removeStickyEvent(stickyEvent); // Now do something with it } // 移除所有事件 EventBus.getDefault().removeAllStickyEvents();
在接收數據時咱們能夠看到threadMode = ThreadMode.MAIN
指定了線程環境,EventBus
還提供了其餘四種線程環境。
設置線程環境
ThreadMode.POSTING
,This is the default,和發佈者處在同一個線程,避免線程阻塞ThreadMode.MAIN
,UI 線程,避免線程阻塞ThreadMode.MAIN_ORDERED
,called in Android’s main thread,有順序的訂閱,避免線程阻塞ThreadMode.BACKGROUND
,called in a background thread. 單後臺線程,也是須要避免線程阻塞ThreadMode.ASYNC
,called in a separate thread,使用場景,網絡請求,內部使用線程池去維護
設置事件優先級
事件的優先級相似廣播的優先級,優先級越高優先得到消息。默認優先級是
0
//在 ui 線程執行 優先級 100 @Subscribe(threadMode = ThreadMode.MAIN, priority = 100) public void onDataSynEvent(DataSynEvent event) { Log.e(TAG, "event---->" + event.getCount()); }
總結
EventBus
的基本使用仍是很簡單的,主要分爲三步
- 引入依賴
- 註冊事件和接收事件
- 發送事件
註冊事件須要和註銷事件成對出現,不然會內存泄露。
並且註冊事件要在onCreate
或者onStart
生命週期中註冊,註銷事件在onStop
或者onDestory
方法中。
發送事件分爲普通事件和粘性事件。
- 普通事件只能在事件註冊以後才能收到。
- 粘性事件能確保事件註冊以後必定能接收到,粘性事件若是不須要了記得要移除。
- 粘性事件的移除又分爲單個事件移除和所有事件移除。
END~
本文同步分享在 博客「_龍衣」(CSDN)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。