您的位置:

Android Event Bus原理解析

一、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