classFindState{ //订阅方法的 list final List<SubscriberMethod> subscriberMethods = new ArrayList<>(); //事件类为 key , Object 为 value(后面可以知道主要是判断是不是 method 以及是否存在 ) final Map<Class, Object> anyMethodByEventType = new HashMap<>(); //方法名和事件类名为 key , 订阅者类对象 为 value final Map<String, Class> subscriberClassByMethodKey = new HashMap<>(); //订阅者类对象,但看源码这个没有用到可能是遗留代码 Class<?> subscriberClass; //订阅者类对象 Class<?> clazz; //是否跳过超类,如果细心的话,可以发现在 findUsingReflectionInSingleClass 中获取 clazz 非继承方法失败的话,会置为 true boolean skipSuperClasses; //订阅者信息 SubscriberInfo subscriberInfo; voidinitForSubscriber(Class<?> subscriberClass){ this.subscriberClass = clazz = subscriberClass; skipSuperClasses = false; subscriberInfo = null; }
booleancheckAdd(Method method, Class<?> eventType){ // 2 level check: 1st level with event type only (fast), 2nd level with complete signature when required. // Usually a subscriber doesn't have methods listening to the same event type. //插入事件类型和方法 Object existing = anyMethodByEventType.put(eventType, method); //如果返回为 Null 表示是新的事件类型和方法 if (existing == null) { returntrue; } else { if (existing instanceof Method) {//判断 existing 为 Method if (!checkAddWithMethodSignature((Method) existing, eventType)) {//通过方法签名检查是否存在 // Paranoia check thrownew IllegalStateException(); } // Put any non-Method object to "consume" the existing Method //用任意非方法对象消费掉这个事件 key 的 value anyMethodByEventType.put(eventType, this); } //如果 existing 不是 Method 则通过签名检查 method return checkAddWithMethodSignature(method, eventType); } }
privatebooleancheckAddWithMethodSignature(Method method, Class<?> eventType){ methodKeyBuilder.setLength(0); methodKeyBuilder.append(method.getName()); methodKeyBuilder.append('>').append(eventType.getName()); //统一用 “方法名>事件类名” 作为 key String methodKey = methodKeyBuilder.toString(); //获取声明这个方法的类对象 Class<?> methodClass = method.getDeclaringClass(); //获取 subscriberClassByMethodKey 中 methodKey 对应的类对象 Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass); if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) {//如果 subscriberClassByMethodKey 不存在类对象或 methodClassOld 与 methodClassOld 是否相同或是另一个类的子类或接口 // Only add if not already found in a sub class returntrue; } else {//反之,subscriberClassByMethodKey 插入 methodKey 对应 methodClassOld // Revert the put, old class is further down the class hierarchy subscriberClassByMethodKey.put(methodKey, methodClassOld); returnfalse; } } //将 clazz 指向非 java/javax/android 包的超类 voidmoveToSuperclass(){ if (skipSuperClasses) { clazz = null; } else { clazz = clazz.getSuperclass(); String clazzName = clazz.getName(); /** Skip system classes, this just degrades performance. */ if (clazzName.startsWith("java.") || clazzName.startsWith("javax.") || clazzName.startsWith("android.")) { clazz = null; } } } }
SubscriberMethod
顺便看看 SubscriberMethod 类的代码(省略部分代码)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/** Used internally by EventBus and generated subscriber indexes. */ publicclassSubscriberMethod{ final Method method; final ThreadMode threadMode; final Class<?> eventType; finalint priority; finalboolean sticky; /** Used for efficient comparison */ String methodString;
看完文档,我们知道 Subscriber Index 是 EventBus 3 上的新技术,所以这里也建议还没学习过 EventBus 的可以跳过 2.X 之前的版本直接学习最新版本。
关于 EventBus 的 Subscriber Index 技术的特点,翻译一下官方解释:
It is an optional optimization to speed up initial subscriber registration.
Subscriber Index 是一个可选的优化技术,用来加速初始化订阅者注册。
The subscriber index can be created during build time using the EventBus annotation processor. While it is not required to use an index, it is recommended on Android for best performance.
Subscriber Index 在编译时使用 EventBus 注解处理器创建,虽然没有规定必须使用它,但是官方推荐使用这种方式,因为它在 Android 上有着最佳的性能。
//根据新的订阅方法的优先级将订阅者插入 subscriptions 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; } }
//从 typesBySubscriber 获取这个订阅者的订阅者方法列表 List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber); if (subscribedEvents == null) {//为空则新建,并插入 typesBySubscriber subscribedEvents = new ArrayList<>(); typesBySubscriber.put(subscriber, subscribedEvents); } subscribedEvents.add(eventType); // 订阅方法是否设置黏性模式 if (subscriberMethod.sticky) { // 是否设置了事件继承 if (eventInheritance) { // Existing sticky events of all subclasses of eventType have to be considered. // Note: Iterating over all events may be inefficient with lots of sticky events, // thus data structure should be changed to allow a more efficient lookup // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>). Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet(); for (Map.Entry<Class<?>, Object> entry : entries) { Class<?> candidateEventType = entry.getKey(); // 判断当前事件类型是否为黏性事件或者其子类 if (eventType.isAssignableFrom(candidateEventType)) { Object stickyEvent = entry.getValue(); // 执行设置了sticky模式的订阅方法 checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } } else { Object stickyEvent = stickyEvents.get(eventType); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } }