文章目录
介绍
优点
- 简化组件之间的通信
- 解耦事件发送者和接收者
- 在 Activity、Fragment 和后台线程中表现良好
- 避免复杂且容易出错的依赖关系和生命周期问题
- 让你的代码更简单
- 很快,很小
- 具有高级功能,如交付线程、订阅者优先级等。
基本用法
导入依赖
implementation "org.greenrobot:eventbus:3.3.1"
- 定义事件:
public static class MessageEvent {
/* Additional fields if needed */ }
-
准备订阅者:声明并注释您的订阅方法,可以选择指定线程模式
@Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MessageEvent event) { // Do something }
注册和取消注册您的订户。例如在 Android 上,活动和片段通常应根据其生命周期进行注册:
@Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { super.onStop(); EventBus.getDefault().unregister(this); }
-
发布活动:
EventBus.getDefault().post(new MessageEvent());
线程模式
POSTING
- 特点:订阅者在发布事件的同一线程中被调用。
- 优点:开销最小,避免了线程切换。
- 适用场景:已知任务简单且快速完成,不依赖主线程。
- 注意:长时间任务可能阻塞发布线程(如是主线程,会导致UI卡顿)。
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(MessageEvent event) {
log(event.message); // 快速返回的简单任务
}
MAIN
-
特点:
- 订阅者在主线程(UI线程)中被调用
- 如果发布线程为主线程,则同步调用(与
POSTING
类似)
-
适用场景:UI更新或需要在主线程完成的轻量任务。
-
注意:避免执行耗时任务,否则会阻塞主线程,导致卡顿。
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
textView.setText(event.message); // 更新UI
}
MAIN_ORDERED
- 特点:
- 在主线程中执行。
- 按顺序执行:事件会一个接一个地处理,不会乱序。
- 适用场景:依赖特定执行顺序的UI更新逻辑。
- 注意:与
MAIN
类似,避免耗时任务,确保任务快速返回。
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMessageEvent(String event) {
Log.d("EventBus", "Event received: " + event); // 按顺序更新UI
}
BACKGROUND
- 特点:
- 如果发布线程为主线程,事件处理方法会切换到后台线程。
- 如果发布线程是非主线程,事件处理方法直接在发布线程中执行。
- 适用场景:后台任务,如数据库存储、文件操作。
- 注意:快速返回,避免阻塞后台线程。
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEvent event) {
saveToDisk(event.message); // 后台存储操作
}
ASYNC
- 特点:事件处理程序始终在独立线程中调用,与发布线程或主线程完全分离。
- 适用场景:耗时操作,如网络请求、复杂计算。
- 注意:避免触发大量异步任务,防止线程池耗尽资源。
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessage(MessageEvent event) {
backend.send(event.message); // 异步网络请求
}
黏性事件
发送事件之后再订阅也能收到该事件
@Subscribe(threadMode = ThreadMode.POSTING, sticky = true)
public void onMessageEvent(MessageEvent messageEvent) {
tv.setText(messageEvent.getMessage());
}
EventBus.getDefault().postSticky(new MessageEvent("SecondActivity的信息"));
源码
构造
public class EventBus {
// 静态变量,存储唯一的 EventBus 实例
// 使用 volatile 关键字,确保多线程环境下变量的可见性和防止指令重排
static volatile EventBus defaultInstance;
public static EventBus getDefault() {
// 将静态变量 defaultInstance 赋值给局部变量 instance,减少对主内存的访问
EventBus instance = defaultInstance;
// 第一次检查,避免不必要的同步开销
if (instance == null) {
// 如果实例未被初始化,进入同步块
synchronized (EventBus.class) {
// 再次将 defaultInstance 的值赋给 instance(看这个时候defaultInstance为不为空)
instance = EventBus.defaultInstance;
// 第二次检查,确保实例仍未被初始化(双重检查锁定)
if (instance == null) {
// 创建新的 EventBus 实例并赋值给 defaultInstance 和局部变量 instance
instance = EventBus.defaultInstance = new EventBus();
}
}
}
return instance;
}
}
public EventBus() {
this(DEFAULT_BUILDER);
}
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
建造者模式
EventBus(EventBusBuilder builder) {
//日志
logger = builder.getLogger();
//这个集合可以根据事件类型获取订阅者
//key:事件类型,value:订阅该事件的订阅者集合
subscriptionsByEventType = new HashMap<>();
//订阅者所订阅的事件集合
//key:订阅者,value:该订阅者订阅的事件集合
typesBySubscriber = new HashMap<>();
//粘性事件集合
//key:事件Class对象,value:事件对象
stickyEvents = new ConcurrentHashMap<>();
//Android主线程处理事件
mainThreadSupport = builder.getMainThreadSupport();
mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
//Background事件发送者
backgroundPoster = new BackgroundPoster(this);
//异步事件发送者
asyncPoster = new AsyncPoster(this);
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
//订阅者订阅事件查找对象
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex);
logSubscriberExceptions = builder.logSubscriberExceptions;
logNoSubscriberMessages = builder.logNoSubscriberMessages;
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
throwSubscriberException = builder.throwSubscriberException;
eventInheritance = builder.eventInheritance;
executorService = builder.executorService;
}
这个方法内部首先通过单例模式创建一个EventBus
对象,在创建EventBus
时最终会调用它的有参构造函数,传入一个EventBus.Builder
对象。在这个有参构造函数内部对属性进行初始化
注册
public void register(Object subscriber) {
// 1、通过反射获取到订阅者的Class对象
Class<?> subscriberClass = subscriber.getClass();
// 2、获取订阅者所订阅事件的集合(1)
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
// 3、遍历集合进行注册
for (SubscriberMethod subscriberMethod : subscriberMethods) {
// 遍历订阅者的订阅方法来完成订阅者的订阅操作
subscribe(subscriber, subscriberMethod);
}
}
}
获取订阅者所订阅事件集合
public class SubscriberMethod {
final Method method;