一、Event Bus是什么
Event Bus是一种消息发布/订阅机制,它允许组件之间进行解耦。在Event Bus中,组件可以将消息发布到某个主题或者订阅某个主题,当主题发布消息时,所有订阅该消息的组件都会收到该消息。
Event Bus是由Otto团队开发的,它依赖注解处理器和Java的反射机制。
二、Event Bus的基本使用方法
在使用Event Bus之前,需要在gradle中添加依赖:
<dependency>
<groupId>org.greenrobot</groupId>
<artifactId>eventbus</artifactId>
<version>3.2.0</version>
<scope>provided</scope>
</dependency>
在发布消息的组件中,需要定义一个事件类,包含需要发布的数据:
public class MessageEvent {
public final String message;
public MessageEvent(String message){
this.message = message;
}
}
发布消息时,需要将事件类的实例传递给Event Bus:
EventBus.getDefault().post(new MessageEvent("Hello World!"));
在订阅消息的组件中,需要定义一个接收方法,该方法使用@Subscribe注解进行标记,并且该方法的参数包含需要订阅的事件类:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event){
Toast.makeText(this, event.message, Toast.LENGTH_SHORT).show();
}
同时需要在onStart方法中注册,onStop方法中取消注册:
@Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
三、Event Bus的原理
Event Bus的原理是基于观察者模式,通过动态的生成代码,实现事件分发的效果。
在订阅者注册时,Event Bus通过注解处理器处理订阅者的类,生成对应的订阅者方法并加入订阅者列表中。在订阅者方法中,Event Bus将接收到的事件对象保存下来并加入事件队列中。
而在事件发布时,Event Bus将事件通过线程池中的线程异步分发出去,Event Bus会遍历订阅者列表,并根据订阅者方法中定义的注解来进行对应订阅者的调用。
为了保证线程的安全,Event Bus默认采用的线程模式是PostThreadMode,即在发布事件的线程中进行订阅者的方法调用。同时Event Bus也提供了其他三种线程模式:MainThread,BackgroundThread和AsyncThread。
四、Event Bus的常见问题和解决方法
1、如何避免方法名一致导致的误调用问题?
使用Event Bus的ProGuard插件,保证订阅者方法的混淆。
2、如何避免内存泄漏问题?
在订阅者中,不要将订阅者本身作为事件对象发布,否则很容易造成内存泄漏。同时在Activity的onStop方法中,一定要调用Event Bus的unregister方法,否则会持有Activity的引用。
3、如何解决发布到BackgroundThread时UI操作的问题?
使用MainThread线程模式,将方法标记为@UiThread即可解决UI操作问题。
五、参考资料
1、官方文档:https://github.com/greenrobot/EventBus
2、博客文章:https://www.jianshu.com/p/303f94e0ce71
3、源码分析:https://blog.csdn.net/u011240877/article/details/79681408