-
EventBus简介
EventBus基于观察者设计模式,通过事件的发送和订阅,方便模块间的通讯与解耦。官方的介绍图如下:
最新版V3.2.0-EventBus模块如下
模块 | 描述 |
---|---|
EventBus | EventBus源码 |
EventBusAnnotationProcessor | EventBus注解处理器源码,V3.0引入,提升效率 |
EventBusPerformance | EventBus与Otto速度测试 |
EventBusTest/EventBusTestJava/EventBusTestSubscriberInJar | EventBus测试工程 |
2.使用示例代码
// gradle引入EventBus依赖
implementation 'org.greenrobot:eventbus:3.2.0'
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 1-1.注册Subscribers
EventBus.getDefault().register(this);
}
@Override
protected void onStart() {
super.onStart();
// 2.Publisher发送事件
EventBus.getDefault().post("Hello World");
}
@Override
protected void onDestroy() {
super.onDestroy();
// 1-3.反注册Subscribers
EventBus.getDefault().unregister(this);
}
// 1-2.定义Subscribers收到事件时的回调处理
@Subscribe
public void hello(String words) {
Log.d("MainActivity", "receive hello event: " + words);
}
}
3.源码分析
-
EventBus.getDefault(),通过单例提供了EventBus的入口
public static EventBus getDefault() { EventBus instance = defaultInstance; if (instance == null) { synchronized (EventBus.class) { instance = EventBus.defaultInstance; if (instance == null) { instance = EventBus.defaultInstance = new EventBus(); } } } return instance; }
-
注册事件订阅者
public void register(Object subscriber) { Class<?> subscriberClass = subscriber.getClass(); List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass); synchronized (this) { for (SubscriberMethod subscriberMethod : subscriberMethods) { subscribe(subscriber, subscriberMethod); } } }
-
subscribe()将订阅者与其事件处理方法联系在一起,在后续发送者发送事件时调用
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) { ...... int size = subscriptions.size(); for (int i = 0; i <= size; i++) { if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) { subscriptions.add(i, newSubscription); break; } } List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber); if (subscribedEvents == null) { subscribedEvents = new ArrayList<>(); typesBySubscriber.put(subscriber, subscribedEvents); } subscribedEvents.add(eventType); ...... }
-
上面register()方法中,创建了SubscriberMethodFinder(订阅者方法搜寻器)对象,该对象是在EventBus构造函数中生成;findSubscriberMethods()方法作用就是找到所有@Subscribe注解的方法
EventBus(EventBusBuilder builder) { ... subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes, builder.strictMethodVerification, builder.ignoreGeneratedIndex); ... }
-
findSubscriberMethods:找到订阅者方法并放入缓存中
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) { List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass); if (subscriberMethods != null) { return subscriberMethods; } if (ignoreGeneratedIndex) { subscriberMethods = findUsingReflection(subscriberClass); } else { subscriberMethods = findUsingInfo(subscriberClass); } if (subscriberMethods.isEmpty()) { throw new EventBusException("Subscriber " + subscriberClass + " and its super classes have no public methods with the @Subscribe annotation"); } else { METHOD_CACHE.put(subscriberClass, subscriberMethods); return subscriberMethods; } }
通过分析ignoreGeneratedIndex默认false, 因此执行subscriberMethods = findUsingInfo(subscriberClass),具体代码如下:
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) { // 准备FindState FindState findState = prepareFindState(); findState.initForSubscriber(subscriberClass); while (findState.clazz != null) { // 获取订阅者信息 findState.subscriberInfo = getSubscriberInfo(findState); if (findState.subscriberInfo != null) { SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods(); for (SubscriberMethod subscriberMethod : array) { if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) { findState.subscriberMethods.add(subscriberMethod); } } } else { // 默认subscriberInfo=null,执行这里的的代码 findUsingReflectionInSingleClass(findState); } // 向订阅者父类查找 findState.moveToSuperclass(); } return getMethodsAndRelease(findState); }
接下来执行 findUsingReflectionInSingleClass(findState),完成了订阅者信息的查找过程,具体代码如下
private void findUsingReflectionInSingleClass(FindState findState) { Method[] methods; try { // This is faster than getMethods, especially when subscribers are fat classes like Activities methods = findState.clazz.getDeclaredMethods(); } catch (Throwable th) { // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149 try { methods = findState.clazz.getMethods(); } catch (LinkageError error) { // super class of NoClassDefFoundError to be a bit more broad... String msg = "Could not inspect methods of " + findState.clazz.getName(); if (ignoreGeneratedIndex) { msg += ". Please consider using EventBus annotation processor to avoid reflection."; } else { msg += ". Please make this class visible to EventBus annotation processor to avoid reflection."; } throw new EventBusException(msg, error); } findState.skipSuperClasses = true; } for (Method method : methods) { int modifiers = method.getModifiers(); if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) { Class<?>[] parameterTypes = method.getParameterTypes(); if (parameterTypes.length == 1) { Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class); if (subscribeAnnotation != null) { Class<?> eventType = parameterTypes[0]; if (findState.checkAdd(method, eventType)) { ThreadMode threadMode = subscribeAnnotation.threadMode(); findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode, subscribeAnnotation.priority(), subscribeAnnotation.sticky())); } } } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) { String methodName = method.getDeclaringClass().getName() + "." + method.getName(); throw new EventBusException("@Subscribe method " + methodName + "must have exactly 1 parameter but has " + parameterTypes.length); } } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) { String methodName = method.getDeclaringClass().getName() + "." + method.getName(); throw new EventBusException(methodName + " is a illegal @Subscribe method: must be public, non-static, and non-abstract"); } } }
-
-
发送事件、事件的处理
post()方法先将事件推到事件队列,之后遍历出队,postSingleEvent()完成单个事件的发送。
public void post(Object event) { PostingThreadState postingState = currentPostingThreadState.get(); List<Object> eventQueue = postingState.eventQueue; eventQueue.add(event); if (!postingState.isPosting) { postingState.isMainThread = isMainThread(); postingState.isPosting = true; if (postingState.canceled) { throw new EventBusException("Internal error. Abort state was not reset"); } try { while (!eventQueue.isEmpty()) { postSingleEvent(eventQueue.remove(0), postingState); } } finally { postingState.isPosting = false; postingState.isMainThread = false; } } }
eventInheritance默认true,lookupAllEventTypes()方法循环所有事件,postSingleEventForEventType()方法发送事件到每个订阅者
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error { Class<?> eventClass = event.getClass(); boolean subscriptionFound = false; // eventInheritance = true,执行下面的代码 if (eventInheritance) { // 向上获取到父类的所有事件 List<Class<?>> eventTypes = lookupAllEventTypes(eventClass); int countTypes = eventTypes.size(); for (int h = 0; h < countTypes; h++) { Class<?> clazz = eventTypes.get(h); // 发送单个事件 subscriptionFound |= postSingleEventForEventType(event, postingState, clazz); } } else { subscriptionFound = postSingleEventForEventType(event, postingState, eventClass); } if (!subscriptionFound) { if (logNoSubscriberMessages) { logger.log(Level.FINE, "No subscribers registered for event " + eventClass); } if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) { post(new NoSubscriberEvent(this, event)); } } }
postSingleEventForEventType()后续代码如下:
// 遍历发送单个事件到订阅者 private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) { CopyOnWriteArrayList<Subscription> subscriptions; synchronized (this) { subscriptions = subscriptionsByEventType.get(eventClass); } if (subscriptions != null && !subscriptions.isEmpty()) { for (Subscription subscription : subscriptions) { postingState.event = event; postingState.subscription = subscription; boolean aborted; try { postToSubscription(subscription, event, postingState.isMainThread); aborted = postingState.canceled; } finally { postingState.event = null; postingState.subscription = null; postingState.canceled = false; } if (aborted) { break; } } return true; } return false; } // 进行线程判断 private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) { switch (subscription.subscriberMethod.threadMode) { case POSTING: invokeSubscriber(subscription, event); break; case MAIN: if (isMainThread) { invokeSubscriber(subscription, event); } else { mainThreadPoster.enqueue(subscription, event); } break; case MAIN_ORDERED: if (mainThreadPoster != null) { mainThreadPoster.enqueue(subscription, event); } else { // temporary: technically not correct as poster not decoupled from subscriber invokeSubscriber(subscription, event); } break; case BACKGROUND: if (isMainThread) { backgroundPoster.enqueue(subscription, event); } else { invokeSubscriber(subscription, event); } break; case ASYNC: asyncPoster.enqueue(subscription, event); break; default: throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode); } } // 通过反射调用订阅者的方法,实现订阅者对事件的处理 void invokeSubscriber(Subscription subscription, Object event) { try { subscription.subscriberMethod.method.invoke(subscription.subscriber, event); } catch (InvocationTargetException e) { handleSubscriberException(subscription, event, e.getCause()); } catch (IllegalAccessException e) { throw new IllegalStateException("Unexpected exception", e); } }
-
小结
从上面的源码分析中,可以看出订阅者(Subscriber)注册事件订阅(register)后,通过订阅(subscribe)将事件处理方法联系起来,发送者(Publisher)发送事件后(post),订阅者在事件处理方法完成接收事件的处理。
4.总结
EventBus从总体上看还是比较简单,主要涉及1.自定义注解、APT 2.观察者设计模式两个方面技术栈。