Android事件总线 浅谈 EventBus
EventBus官方文档是这么写的:EventBus is a publish/subscribe event bus optimized for Android.
也就是说EventBus是Android下高效的发布/订阅事件总线机制。
EventBus可以代替传统的Intent,Handler,Broadcast或接口函数在Fragment,Activity,Service,线程之间传递数据,执行方法。
我们先来看看官方文档对EventBus的介绍:
- simplifies the communication between components
- decouples event senders and receivers
- performs well with Activities, Fragments, and background threads
- avoids complex and error-prone dependencies and life cycle issues
- makes your code simpler
- is fast
- is tiny (~50k jar)
- is proven in practice by apps with 100,000,000+ installs
- has advanced features like delivery threads, subscriber priorities, etc.
从文档介绍中可以看出EventBus有很多优点:
(1)简化组件间的通讯(2)事件发布者和订阅者解耦(3)在Activity、Fragment和子线程有优秀的执行能力(4)避免复杂和容易出错的依赖关系和生命周期问题(5)使你的代码更简单(EventBus采用了一种发布订阅设计模式(Publish/Subsribe),或称为观察者设计模式)(6)快(7)小(~ 50K的jar)(8)具有交付线程、用户优先级等高级功能
上面说了,EventBus是一个观察者模式的实现,它就有如下三个要素:
Event:事件(可以使任意类型对象)Subscriber:事件订阅者(接收特定的事件,onEvent、onEventMainThread、onEventBackgroundThread、onEventAsync)Publisher:事件发布者(可以通过post(Object)在任意线程任意位置发送事件)
从如下官方这个图就很直观的说明了这种观察者模式的架构:
1.下载EventBus
Github下载:
https://github.com/greenrobot/EventBus
EventBus jar下载:
https://github.com/greenrobot/EventBus/releases
2.EventBus的用法
(1)首先引入EventBus
Eclipse:将EventBus.jar添加到libs下,Add to Build Path
Android Studio:在工程gradle中添加:compile ‘de.greenrobot:eventbus:3.0.0-beta1’
(2)定义事件, 定义一个类,继承默认的Object即可,用于区分事件和传输数据, 本例为MsgEvent(如有多个,可定义多个MsgEvent)。
(3)添加订阅者和取消订阅
添加订阅者:EventBus.getDefault().register(this); 将所在类作为订阅者,框架会通过反射机制获取所有方法及其参数。
取消订阅:EventBus.getDefault().unregister(this); 当订阅者不再被使用,或者被关闭时,最好进行取消订阅,不再接受事件消息。
订阅者所在类可以定义如下一个或多个方法用以接收事件:
// 与发布者在同一个线程public void onEvent(MsgEvent msg){}// 执行在主线程public void onEventMainThread(MsgEvent msg){}// 执行在子线程public void onEventBackgroundThread(MsgEvent msg){}// 执行在一个新的子线程public void onEventAsync(MsgEvent msg){}
(4)发布者发布事件:EventBus.getDefault().post(new MsgEvent(“主线程发的消息1”));
一旦执行了此方法, 所有订阅者都会执行第二步定义的方法。
(5)注意事项:发布者post方法参数是Object类型,也就是可以发布任何事件。订阅者接受消息时,只要定义的是第二步四个方法任意一个,并且参数和发布者发布的一致,即可被执行。发布者也可以通过第二步接收消息,订阅者也可以作为发布者发消息给自己。
3.EventBus的一个使用实例
下面我们实现EventBus代替传统的Handler在Fragment之间传递数据;
这里假设AFragment传递数据到BFragment。
(1)创建事件MsgEvent
public class MsgEvent { private String msg; public MsgEvent(String msg) { super(); this.msg = msg; } public String getMsg() { return msg; }}
(4)在BFragment中添加订阅者
public class BFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 界面创建时,订阅事件, 接受消息 EventBus.getDefault().register(this); } @Override public void onDestroy() { super.onDestroy(); // 界面销毁时,取消订阅 EventBus.getDefault().unregister(this); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_b, null); return view; } /** * 与发布者在同一个线程 * @param msg 事件MsgEvent */ public void onEvent(MsgEvent msg){ String message = msg.getMsg(); } /** * 执行在主线程,这里可以将子线程加载到的数据直接设置到界面中 * @param msg 事件MsgEvent */ public void onEventMainThread(MsgEvent msg){ String message = msg.getMsg(); } /** * 执行在子线程,如果发布者是子线程则直接执行,如果发布者不是子线程,则创建一个再执行,此处可能会有线程阻塞问题 * @param msg 事件MsgEvent */ public void onEventBackgroundThread(MsgEvent msg){ String message = msg.getMsg(); } /** * 执行在一个新的子线程,适用于多个线程任务处理, 内部有线程池管理 * @param msg 事件MsgEvent */ public void onEventAsync(MsgEvent msg){ String message = msg.getMsg(); }}
(3)发布者发布事件(在AFragment主线程中)
EventBus.getDefault().post(new MsgEvent("主线程发的消息"));
更多相关文章
- Android防止过快点击造成多次事件执行(防止按钮重复点击)
- android线程池的封装工具类
- Android正确关闭线程
- Android热插拔事件处理流程--Vold
- Android 主线程子线程执行关系