EventBus 是一个流行的事件发布/订阅框架,主要用于简化 Android 应用中不同组件之间的通信。它的设计基于观察者模式,可以有效地减少组件间的耦合性,使得代码更加模块化和可维护。
下面是 EventBus 的实现原理,结合其源码进行说明:
1. 注册订阅者 (Registering Subscribers)
在 EventBus 中,一个订阅者通常是一个 Android 组件(如 Activity 或 Fragment),它通过调用 EventBus.getDefault().register(this) 方法来注册自身。在注册时,EventBus 会通过反射机制扫描订阅者的类,查找带有 @Subscribe 注解的方法。这些方法就是事件处理方法。
源码中相关的关键部分包括 EventBus 的 register 方法:
Java
1public void register(Object subscriber) {
2    Util.ensureBackgroundThread();
3    Set<Class<?>> subscriberTypes = subscriberTypes(subscriber);
4    for (Class<?> subscriberType : subscriberTypes) {
5        SubscriberMethod[] methods = findSubscriberMethods(subscriberType);
6        for (SubscriberMethod method : methods) {
7            method.subscriber = subscriber;
8            method.eventType = method.rawEventType;
9            method.threadMode = method.rawThreadMode;
10            method.priority = method.rawPriority;
11            method.sticky = method.rawSticky;
12            registerSubscriber(subscriber, method);
13        }
14    }
15}findSubscriberMethods 方法会找到所有带有 @Subscribe 注解的方法,并封装成 SubscriberMethod 对象。
2. 发布事件 (Posting Events)
发布事件是通过调用 EventBus.getDefault().post(event) 方法完成的。这个方法会将事件放入一个事件队列中,并且根据事件类型和线程模式,调用相应的处理方法。
源码中的关键部分是 EventBus 的 post 方法:
Java
1public void post(Object event) {
2    Util.ensureBackgroundThread();
3    if (event == null) throw new NullPointerException("Event must not be null");
4    Class<?> eventClass = event.getClass();
5    synchronized (this) {
6        deliver(eventClass, event);
7    }
8}deliver 方法会查找与事件类型相匹配的所有订阅者方法,并按照优先级排序,然后调用 postToSubscription 方法来处理事件。
3. 处理事件 (Handling Events)
事件处理是在 postToSubscription 方法中完成的,它会根据 SubscriberMethod 的线程模式来决定在哪个线程中调用事件处理方法。常见的线程模式有 POSTING, MAIN, ASYNC, BACKGROUND。
源码中处理事件的部分涉及到 EventBus 的 postToSubscription 方法:
Java
1void postToSubscription(Event event, Subscription subscription) {
2    SubscriberMethod method = subscription.method;
3    if (method.threadMode == ThreadMode.POSTING) {
4        postToPostingThread(event, subscription);
5    } else if (method.threadMode == ThreadMode.MAIN) {
6        postToMainThread(event, subscription);
7    } else if (method.threadMode == ThreadMode.ASYNC) {
8        postToAsyncThread(event, subscription);
9    } else if (method.threadMode == ThreadMode.BACKGROUND) {
10        postToBackgroundThread(event, subscription);
11    }
12}每个线程模式都有对应的 postToXXXThread 方法,它们负责在正确的线程上下文中执行事件处理方法。
4. 取消注册 (Unregistering Subscribers)
当一个订阅者不再需要接收事件时,它应该调用 EventBus.getDefault().unregister(this) 方法来取消注册。这样可以避免内存泄漏和不必要的事件处理。
以上就是 EventBus 的基本工作原理。通过上述机制,EventBus 提供了一种简洁高效的方式来处理组件间通信,减少了组件之间的直接依赖,提高了代码的可测试性和可维护性。