本系列文章主要分析 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 的过程;