本系列文章主要分析 EventBus 框架的架构和原理,,基于最新的 3.1.0 版本。
这是 EventBus 开源库的地址,大家可以直接访问https://github.com/greenrobot/EventBus
本篇文章是 EventBus 的第二篇,主要分析 Subscribe 注解的处理;
Eventbus 翻译过来就是事件总线,用于简化组件和组件,线程和线程之间的消息通信,可以捆成是 Handler + Thread 的替代品。
1 回顾 我们在使用的过程中,需要设置接收消息的方法:
1 2 3 4 @Subscribe (threadMode = ThreadMode.MAIN)public void onEventMainThread (Object object) { ... ... ... }
注解 Subscribe 可以说是 EventBus 的核心了,我们知道,3.x 版本之前,EventBus 使用的是运行时注解,其实就是 Java 的反射机制,但是这带来了性能的损耗!
因此,从 3.x 开始,Eventbus 引入了编译时注解处理的特性,核心类就是 EventBusAnnotationProcessor!
我们来看看注解的定义:
1 2 3 4 5 6 7 8 9 10 @Documented @Retention (RetentionPolicy.RUNTIME)@Target ({ElementType.METHOD})public @interface Subscribe { ThreadMode threadMode () default ThreadMode.POSTING ; boolean sticky () default false ; int priority () default 0 ; }
可以看到,Subscribe 用于修饰方法,并且可以保留到运行时,这是因为默认情况下,EventBus 是通过运行时注解,反射加载方法的,除非开启编译时注解处理机制;
2 EventBusAnnotationProcessor - Subscribe 处理 浏览 EventBus 的源码目录,我们能看到处理 Subscribe 注解的是 EventBusAnnotationProcessor 类,依然是编译时注解,动态生成代码:
1 2 3 @SupportedAnnotationTypes ("org.greenrobot.eventbus.Subscribe" )@SupportedOptions (value = {"eventBusIndex" , "verbose" })public class EventBusAnnotationProcessor extends AbstractProcessor {
可以看到,它支持的只有一个注解:Subscribe
同时他支持两个配置属性:
eventBusIndex:是否开启编译时注解处理,这个特性是 3.x 版本新增的,也就是将运行时的处理放到了编译时注解处理,动态生成 java 代码,用于提升框架的性能;
verbose:用于控制 log,调试使用;
这两个属性是在 gradle 中配置的;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 android { defaultConfig { javaCompileOptions { annotationProcessorOptions { arguments = [eventBusIndex: 'com.monster.android.wild.MyEventBusIndex' , verbose : "true" ] } } } } dependencies { api 'org.greenrobot:eventbus:3.1.0' annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.0.1' }
我们在下面的分析中就能看到,注解处理器对于这几个参数的处理:
2.1 成员变量 EventBusAnnotationProcessor 内部如下的变量和常量:
1 2 public static final String OPTION_EVENT_BUS_INDEX = "eventBusIndex" ;public static final String OPTION_VERBOSE = "verbose" ;
上面的变量用于获取 gradle 的环境变量;
1 2 3 4 5 6 7 8 private final ListMap<TypeElement, ExecutableElement> methodsByClass = new ListMap<>(); private final Set<TypeElement> classesToSkip = new HashSet<>();private boolean writerRoundDone;private int round;private boolean verbose;
2.2 process 依然是核心方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 @Override public boolean process (Set<? extends TypeElement> annotations, RoundEnvironment env) { Messager messager = processingEnv.getMessager(); try { String index = processingEnv.getOptions().get(OPTION_EVENT_BUS_INDEX); if (index == null ) { messager.printMessage(Diagnostic.Kind.ERROR, "No option " + OPTION_EVENT_BUS_INDEX + " passed to annotation processor" ); return false ; } verbose = Boolean.parseBoolean(processingEnv.getOptions().get(OPTION_VERBOSE)); int lastPeriod = index.lastIndexOf('.' ); String indexPackage = lastPeriod != -1 ? index.substring(0 , lastPeriod) : null ; round++; if (verbose) { messager.printMessage(Diagnostic.Kind.NOTE, "Processing round " + round + ", new annotations: " + !annotations.isEmpty() + ", processingOver: " + env.processingOver()); } if (env.processingOver()) { if (!annotations.isEmpty()) { messager.printMessage(Diagnostic.Kind.ERROR, "Unexpected processing state: annotations still available after processing over" ); return false ; } } if (annotations.isEmpty()) { return false ; } if (writerRoundDone) { messager.printMessage(Diagnostic.Kind.ERROR, "Unexpected processing state: annotations still available after writing." ); } collectSubscribers(annotations, env, messager); checkForSubscribersToSkip(messager, indexPackage); if (!methodsByClass.isEmpty()) { createInfoIndexFile(index); } else { messager.printMessage(Diagnostic.Kind.WARNING, "No @Subscribe annotations found" ); } writerRoundDone = true ; } catch (RuntimeException e) { e.printStackTrace(); messager.printMessage(Diagnostic.Kind.ERROR, "Unexpected error in EventBusAnnotationProcessor: " + e); } return true ; }
整个流程很简单,不多 say;
2.2.1 collectSubscribers - 收集 收集注解 Subscribe 修饰的元素;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private void collectSubscribers (Set<? extends TypeElement> annotations, RoundEnvironment env, Messager messager) { for (TypeElement annotation : annotations) { Set<? extends Element> elements = env.getElementsAnnotatedWith(annotation); for (Element element : elements) { if (element instanceof ExecutableElement) { ExecutableElement method = (ExecutableElement) element; if (checkHasNoErrors(method, messager)) { TypeElement classElement = (TypeElement) method.getEnclosingElement(); methodsByClass.putElement(classElement, method); } } else { messager.printMessage(Diagnostic.Kind.ERROR, "@Subscribe is only valid for methods" , element); } } } }
2.2.1.1 checkHasNoErrors 检查是否有错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private boolean checkHasNoErrors (ExecutableElement element, Messager messager) { if (element.getModifiers().contains(Modifier.STATIC)) { messager.printMessage(Diagnostic.Kind.ERROR, "Subscriber method must not be static" , element); return false ; } if (!element.getModifiers().contains(Modifier.PUBLIC)) { messager.printMessage(Diagnostic.Kind.ERROR, "Subscriber method must be public" , element); return false ; } List<? extends VariableElement> parameters = ((ExecutableElement) element).getParameters(); if (parameters.size() != 1 ) { messager.printMessage(Diagnostic.Kind.ERROR, "Subscriber method must have exactly 1 parameter" , element); return false ; } return true ; }
不多说;
2.2.2 checkForSubscribersToSkip 跳过一些订阅者:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 private void checkForSubscribersToSkip (Messager messager, String myPackage) { for (TypeElement skipCandidate : methodsByClass.keySet()) { TypeElement subscriberClass = skipCandidate; while (subscriberClass != null ) { if (!isVisible(myPackage, subscriberClass)) { boolean added = classesToSkip.add(skipCandidate); if (added) { String msg; if (subscriberClass.equals(skipCandidate)) { msg = "Falling back to reflection because class is not public" ; } else { msg = "Falling back to reflection because " + skipCandidate + " has a non-public super class" ; } messager.printMessage(Diagnostic.Kind.NOTE, msg, subscriberClass); } break ; } List<ExecutableElement> methods = methodsByClass.get(subscriberClass); if (methods != null ) { for (ExecutableElement method : methods) { String skipReason = null ; VariableElement param = method.getParameters().get(0 ); TypeMirror typeMirror = getParamTypeMirror(param, messager); if (!(typeMirror instanceof DeclaredType) || !(((DeclaredType) typeMirror).asElement() instanceof TypeElement)) { skipReason = "event type cannot be processed" ; } if (skipReason == null ) { TypeElement eventTypeElement = (TypeElement) ((DeclaredType) typeMirror).asElement(); if (!isVisible(myPackage, eventTypeElement)) { skipReason = "event type is not public" ; } } if (skipReason != null ) { boolean added = classesToSkip.add(skipCandidate); if (added) { String msg = "Falling back to reflection because " + skipReason; if (!subscriberClass.equals(skipCandidate)) { msg += " (found in super class for " + skipCandidate + ")" ; } messager.printMessage(Diagnostic.Kind.NOTE, msg, param); } break ; } } } subscriberClass = getSuperclass(subscriberClass); } } }
可以看到,默认我们获得的是注解方法所在的当前类,但是 while 循环还会继续处理其父类;
先处理子类,再处理父类;
被注解的方法的第一个参数必须是要处理的消息;
消息类型必须是类/接口的实现;
2.2.2.1 isVisible 用来判断注解方法所属的类是否满足条件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 private boolean isVisible (String myPackage, TypeElement typeElement) { Set<Modifier> modifiers = typeElement.getModifiers(); boolean visible; if (modifiers.contains(Modifier.PUBLIC)) { visible = true ; } else if (modifiers.contains(Modifier.PRIVATE) || modifiers.contains(Modifier.PROTECTED)) { visible = false ; } else { String subscriberPackage = getPackageElement(typeElement).getQualifiedName().toString(); if (myPackage == null ) { visible = subscriberPackage.length() == 0 ; } else { visible = myPackage.equals(subscriberPackage); } } return visible; }
参数 myPackage 是我们 eventBusIndex 指定的要动态生成的 java 类的 class Name;
参数 TypeElement typeElement 则是注解方法所在的类元素;
可以看到,注解方法所属的类必须要满足一下的条件:
如果是 public ,那就是可见的 visible 为 true;
如果是 private/protected ,那就是不可见的;
如果是 default ,那么 必须和 eventBusIndex 指定的要动态生成的 java 类属于同一个包下;
2.2.2.1.1 getPackageElement 获得注解方法所属类的包元素:
1 2 3 4 5 6 7 8 private PackageElement getPackageElement (TypeElement subscriberClass) { Element candidate = subscriberClass.getEnclosingElement(); while (!(candidate instanceof PackageElement)) { candidate = candidate.getEnclosingElement(); } return (PackageElement) candidate; }
这里用到了 TypeElement. getenclosingelement() 的方法:
返回封装此元素(非严格意义上)的最里层元素。
如果此元素的声明在词法上直接封装在另一个元素的声明中,则返回那个封装元素。 如果此元素是顶层类型,则返回它的包。 如果此元素是一个包,则返回 null。 如果此元素是一个类型参数,则返回 null。
2.2.2.2 getParamTypeMirror 获取注解方法的参数的类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private TypeMirror getParamTypeMirror (VariableElement param, Messager messager) { TypeMirror typeMirror = param.asType(); if (typeMirror instanceof TypeVariable) { TypeMirror upperBound = ((TypeVariable) typeMirror).getUpperBound(); if (upperBound instanceof DeclaredType) { if (messager != null ) { messager.printMessage(Diagnostic.Kind.NOTE, "Using upper bound type " + upperBound + " for generic parameter" , param); } typeMirror = upperBound; } } return typeMirror; }
这里我们用到了这个方法 TypeVariable.getUpperBound()
返回:此类型变量的上边界
如果此类型变量被声明为没有明确上边界,则结果为 java.lang.object
。 如果此类型变量被声明为有多个上边界,则结果是一个交集类型(建模为 declaredtype
)。 通过检查结果的超类型,可以发现个别边界。
这个是什么意思呢?举个简单的栗子,下面是我们的消息类:
1 2 class Message <T > extends BaseMessage {} class Message <T > {}
这样解释就简单了吧!
2.2.2.3 getSuperclass 获取当前类的父类元素:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private TypeElement getSuperclass (TypeElement type) { if (type.getSuperclass().getKind() == TypeKind.DECLARED) { TypeElement superclass = (TypeElement) processingEnv.getTypeUtils().asElement(type.getSuperclass()); String name = superclass.getQualifiedName().toString(); if (name.startsWith("java." ) || name.startsWith("javax." ) || name.startsWith("android." )) { return null ; } else { return superclass; } } else { return null ; } }
TypeKind 是枚举,保存了 Java 定义的所有的类型数据!
2.2.3 createInfoIndexFile 动态生成 java 类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 private void createInfoIndexFile (String index) { BufferedWriter writer = null ; try { JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(index); int period = index.lastIndexOf('.' ); String myPackage = period > 0 ? index.substring(0 , period) : null ; String clazz = index.substring(period + 1 ); writer = new BufferedWriter(sourceFile.openWriter()); if (myPackage != null ) { writer.write("package " + myPackage + ";\n\n" ); } writer.write("import org.greenrobot.eventbus.meta.SimpleSubscriberInfo;\n" ); writer.write("import org.greenrobot.eventbus.meta.SubscriberMethodInfo;\n" ); writer.write("import org.greenrobot.eventbus.meta.SubscriberInfo;\n" ); writer.write("import org.greenrobot.eventbus.meta.SubscriberInfoIndex;\n\n" ); writer.write("import org.greenrobot.eventbus.ThreadMode;\n\n" ); writer.write("import java.util.HashMap;\n" ); writer.write("import java.util.Map;\n\n" ); writer.write("/** This class is generated by EventBus, do not edit. */\n" ); writer.write("public class " + clazz + " implements SubscriberInfoIndex {\n" ); writer.write(" private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;\n\n" ); writer.write(" static {\n" ); writer.write(" SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();\n\n" ); writeIndexLines(writer, myPackage); writer.write(" }\n\n" ); writer.write(" private static void putIndex(SubscriberInfo info) {\n" ); writer.write(" SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);\n" ); writer.write(" }\n\n" ); writer.write(" @Override\n" ); writer.write(" public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {\n" ); writer.write(" SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);\n" ); writer.write(" if (info != null) {\n" ); writer.write(" return info;\n" ); writer.write(" } else {\n" ); writer.write(" return null;\n" ); writer.write(" }\n" ); writer.write(" }\n" ); writer.write("}\n" ); } catch (IOException e) { throw new RuntimeException("Could not write source for " + index, e); } finally { if (writer != null ) { try { writer.close(); } catch (IOException e) { } } } }
这里的代码有些 low,竟然是硬编码写进去的;
生成了的代码会涉及到如下的类:
1 2 3 4 5 import org.greenrobot.eventbus.meta.SimpleSubscriberInfo;import org.greenrobot.eventbus.meta.SubscriberMethodInfo;import org.greenrobot.eventbus.meta.SubscriberInfo;import org.greenrobot.eventbus.meta.SubscriberInfoIndex;import org.greenrobot.eventbus.ThreadMode;
可以看到,这几个类定义在 eventbus 模块里,简单的说下:
SimpleSubscriberInfo :表示一个订阅者,就是 Subscribe 注解所在的类;
SubscriberMethodInfo :表示一个订阅方法,就是 Subscribe 注解的方法;
SubscriberInfo :接口,SimpleSubscriberInfo 继承了 AbstractSubscriberInfo,而 AbstractSubscriberInfo 实现了 SubscriberInfo 接口,适配器模式 ;
SubscriberInfoIndex :接口,我们动态生成的 Java 类,实现了该接口;
ThreadMode :枚举类型,表示线程类型;
这里我们不多关注;
2.2.3.1 writeIndexLines 这里就是将 methodsByClass 中收集到的信息写入到动态 java 类中;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 private void writeIndexLines (BufferedWriter writer, String myPackage) throws IOException { for (TypeElement subscriberTypeElement : methodsByClass.keySet()) { if (classesToSkip.contains(subscriberTypeElement)) { continue ; } String subscriberClass = getClassString(subscriberTypeElement, myPackage); if (isVisible(myPackage, subscriberTypeElement)) { writeLine(writer, 2 , "putIndex(new SimpleSubscriberInfo(" + subscriberClass + ".class," , "true," , "new SubscriberMethodInfo[] {" ); List<ExecutableElement> methods = methodsByClass.get(subscriberTypeElement); writeCreateSubscriberMethods(writer, methods, "new SubscriberMethodInfo" , myPackage); writer.write(" }));\n\n" ); } else { writer.write(" // Subscriber not visible to index: " + subscriberClass + "\n" ); } } }
第二个参数表示的是否检查父类:shouldCheckSuperclass ,传入的是 true;
2.2.3.1.1 getClassString 获取类名;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private String getClassString (TypeElement typeElement, String myPackage) { PackageElement packageElement = getPackageElement(typeElement); String packageString = packageElement.getQualifiedName().toString(); String className = typeElement.getQualifiedName().toString(); if (packageString != null && !packageString.isEmpty()) { if (packageString.equals(myPackage)) { className = cutPackage(myPackage, className); } else if (packageString.equals("java.lang" )) { className = typeElement.getSimpleName().toString(); } } return className; }
这里调用内部的 cutPackage 去截取类名!
代码简单,就 String 的基本操作。。。
2.2.3.1.2 writeCreateSubscriberMethods 将方法信息写入到 java 类中,参数 String callPrefix 的值:”new SubscriberMethodInfo”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 private void writeCreateSubscriberMethods (BufferedWriter writer, List<ExecutableElement> methods, String callPrefix, String myPackage) throws IOException { for (ExecutableElement method : methods) { List<? extends VariableElement> parameters = method.getParameters(); TypeMirror paramType = getParamTypeMirror(parameters.get(0 ), null ); TypeElement paramElement = (TypeElement) processingEnv.getTypeUtils().asElement(paramType); String methodName = method.getSimpleName().toString(); String eventClass = getClassString(paramElement, myPackage) + ".class" ; Subscribe subscribe = method.getAnnotation(Subscribe.class); List<String> parts = new ArrayList<>(); parts.add(callPrefix + "(\"" + methodName + "\"," ); String lineEnd = ")," ; if (subscribe.priority() == 0 && !subscribe.sticky()) { if (subscribe.threadMode() == ThreadMode.POSTING) { parts.add(eventClass + lineEnd); } else { parts.add(eventClass + "," ); parts.add("ThreadMode." + subscribe.threadMode().name() + lineEnd); } } else { parts.add(eventClass + "," ); parts.add("ThreadMode." + subscribe.threadMode().name() + "," ); parts.add(subscribe.priority() + "," ); parts.add(subscribe.sticky() + lineEnd); } writeLine(writer, 3 , parts.toArray(new String[parts.size()])); if (verbose) { processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Indexed @Subscribe at " + method.getEnclosingElement().getSimpleName() + "." + methodName + "(" + paramElement.getSimpleName() + ")" ); } } }
这个过程是处理注解方法和注解参数的过程;
3 动态 Java 类实例 我们可以看下动态生成的 Java 类实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package com.coolqi.top;import org.greenrobot.eventbus.meta.SimpleSubscriberInfo;import org.greenrobot.eventbus.meta.SubscriberMethodInfo;import org.greenrobot.eventbus.meta.SubscriberInfo;import org.greenrobot.eventbus.meta.SubscriberInfoIndex;import org.greenrobot.eventbus.ThreadMode;import java.util.HashMap;import java.util.Map;public class moduleAppIndex implements SubscriberInfoIndex { private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX; static { SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>(); putIndex(new SimpleSubscriberInfo(com.coolqi.ui.EditPicActivity.class, true , new SubscriberMethodInfo[] { new SubscriberMethodInfo("onEventMainThread" , com.coolqi.common.beans.MessageEvent.class), new SubscriberMethodInfo("onEventMainThread2" , com.coolqi.common.beans.MessageEvent.class, ThreadMode.ASYNC, 1 , true ), })); putIndex(new SimpleSubscriberInfo(com.coolqi.ui.ChangeDateActivity.class, true , new SubscriberMethodInfo[] { new SubscriberMethodInfo("onEventMainThread" , com.coolqi.common.beans.MessageEvent.class), })); putIndex(new SimpleSubscriberInfo(com.coolqi.ui.normal.ExhibitionWebFragment.class, true , new SubscriberMethodInfo[] { new SubscriberMethodInfo("onShowMessageChatNumberEvent" , com.gensee.kzkt_res.bean.MessageChatNumber.class), new SubscriberMethodInfo("onEventMainThread" , com.coolqi.common.beans.MessageEvent.class), })); } private static void putIndex (SubscriberInfo info) { SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info); } @Override public SubscriberInfo getSubscriberInfo (Class<?> subscriberClass) { SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass); if (info != null ) { return info; } else { return null ; } }
下面我们简单的看下涉及到的类和接口,这些类都位于 eventbus 模块中!
后面再分析的时候,我们就不再过多关注这些类了!
3.1 SubscriberInfoIndex 接口,动态生成的类实现该接口:
1 2 3 4 public interface SubscriberInfoIndex { SubscriberInfo getSubscriberInfo (Class<?> subscriberClass) ; }
3.2 SubscriberInfo 接口,订阅者类实现该接口:
1 2 3 4 5 6 7 8 9 public interface SubscriberInfo { Class<?> getSubscriberClass(); SubscriberMethod[] getSubscriberMethods(); SubscriberInfo getSuperSubscriberInfo () ; boolean shouldCheckSuperclass () ; }
3.3 AbstractSubscriberInfo 抽象类,实现了 SubscriberInfo 接口,并实现了其部分接口,适配器模式 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 public abstract class AbstractSubscriberInfo implements SubscriberInfo { private final Class subscriberClass; private final Class<? extends SubscriberInfo> superSubscriberInfoClass; private final boolean shouldCheckSuperclass; protected AbstractSubscriberInfo (Class subscriberClass, Class<? extends SubscriberInfo> superSubscriberInfoClass, boolean shouldCheckSuperclass) { this .subscriberClass = subscriberClass; this .superSubscriberInfoClass = superSubscriberInfoClass; this .shouldCheckSuperclass = shouldCheckSuperclass; } @Override public Class getSubscriberClass () { return subscriberClass; } @Override public SubscriberInfo getSuperSubscriberInfo () { if (superSubscriberInfoClass == null ) { return null ; } try { return superSubscriberInfoClass.newInstance(); } catch (InstantiationException | IllegalAccessException e) { throw new RuntimeException(e); } } @Override public boolean shouldCheckSuperclass () { return shouldCheckSuperclass; } protected SubscriberMethod createSubscriberMethod (String methodName, Class<?> eventType) { return createSubscriberMethod(methodName, eventType, ThreadMode.POSTING, 0 , false ); } protected SubscriberMethod createSubscriberMethod (String methodName, Class<?> eventType, ThreadMode threadMode) { return createSubscriberMethod(methodName, eventType, threadMode, 0 , false ); } protected SubscriberMethod createSubscriberMethod (String methodName, Class<?> eventType, ThreadMode threadMode, int priority, boolean sticky) { try { Method method = subscriberClass.getDeclaredMethod(methodName, eventType); return new SubscriberMethod(method, eventType, threadMode, priority, sticky); } catch (NoSuchMethodException e) { throw new EventBusException("Could not find subscriber method in " + subscriberClass + ". Maybe a missing ProGuard rule?" , e); } } }
3.4 SimpleSubscriberInfo 订阅类,继承了 AbstractSubscriberInfo 类,适配器模式 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class SimpleSubscriberInfo extends AbstractSubscriberInfo { private final SubscriberMethodInfo[] methodInfos; public SimpleSubscriberInfo (Class subscriberClass, boolean shouldCheckSuperclass, SubscriberMethodInfo[] methodInfos) { super (subscriberClass, null , shouldCheckSuperclass); this .methodInfos = methodInfos; } @Override public synchronized SubscriberMethod[] getSubscriberMethods() { int length = methodInfos.length; SubscriberMethod[] methods = new SubscriberMethod[length]; for (int i = 0 ; i < length; i++) { SubscriberMethodInfo info = methodInfos[i]; methods[i] = createSubscriberMethod(info.methodName, info.eventType, info.threadMode, info.priority, info.sticky); } return methods; } }
不多说了!
4 总结 本篇文章,分析了 eventbus 的注解是如何处理的,生成了哪些类,类的关系如何(适配器模式);
下篇文章,分析 register 的过程;