背景
在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源创计划”,欢迎正在阅读的你也加入,一块儿分享。