EventBus源码解析

702 阅读12分钟

EventBus 是一款在 Android 开发中使用的发布/订阅事件总线框架,基于观察者模式,将事件的接收者和发送者分开,简化了组件之间的通信。既然是源码分析当然得从用法开始讲起。至于如何引库这里先暂时不介绍了,后面会介绍。 使用时我们一般会在fragment或Activity中先注册register和取消注册unregister,然后在其中注册一个Event(@Subscribe public void onEvent(xxx)),最后在需要发送事件的地方调用post或postSticky方法将事件发送到订阅者中。那就先从注册开始。EventBus.getDefault().register(this)。 首先拆成两部分,第一步为getDefault

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;
}

其实就是获取EventBus这个单例对象,其中的构造函数如下

EventBus(EventBusBuilder builder) {
    logger = builder.getLogger();
    //key为onEvent方法中的参数类,value为Subscription,
    //Subscription的构造函数参数为当前注册eventBus的类(fragment,activity等)以及一个onEvent方法
    subscriptionsByEventType = new HashMap<>();
    //key为当前注册eventBus的类(fragment,activity等),value则是当前类中所有onEvent方法参数的集合
    typesBySubscriber = new HashMap<>();
    //粘性事件
    stickyEvents = new ConcurrentHashMap<>();
    //包装了主线程handler的类
    mainThreadSupport = builder.getMainThreadSupport();
    //用于向主线程发送消息的handler
    mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
    //用于向后台线程发事件,主要针对于ThreadMode.BACKGROUND
    //在Android中订阅者将在后台线程中订阅。如果发布线程不是主线程,则将在发布线程中直接调用订阅者方法
    //如果发布线程是主线程,则使用单个后台线程,该线程按顺序传递其所有事件,这里的后台线程不能有阻塞任务
    backgroundPoster = new BackgroundPoster(this);
    //用于向后台线程发事件,主要针对于ThreadMode.ASYNC订阅者将在单独的线程中调用。
    // 这始终独立于发布线程和主线程。 发布事件永远不会等待使用此模式的订阅者方法。 订阅者方法如果执行可能需要一些时间,则应使用此模式
    asyncPoster = new AsyncPoster(this);
    //APT生成类的个数
    indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
    //查询订阅的方法
    subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
            builder.strictMethodVerification, builder.ignoreGeneratedIndex);
    //线程池
    executorService = builder.executorService;

    //下面这些就可以暂且不看
    logSubscriberExceptions = builder.logSubscriberExceptions;
    logNoSubscriberMessages = builder.logNoSubscriberMessages;
    sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
    sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
    throwSubscriberException = builder.throwSubscriberException;
    eventInheritance = builder.eventInheritance;


}

这里面总结出来就是一些初始化工作,具体的已经在注释中标出来了,在接下来的介绍中会一一介绍这些变量的用途。紧接着是register方法

public void register(Object subscriber) {
    //拿到当前注册的class
    Class<?> subscriberClass = subscriber.getClass();
    //找到当前类中所有要注册的方法
    List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
    synchronized (this) {
        for (SubscriberMethod subscriberMethod : subscriberMethods) {
            //注册方法
            subscribe(subscriber, subscriberMethod);
        }
    }
}

首先是拿到当前注册的类,然后根据这个类去寻找类中所有要注册的方法。这里就需要重点看

List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);

首先 subscriberMethodFinder从字面意思可以看出他就是订阅方法查找器,它是在getDefault中初始化的

subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
        builder.strictMethodVerification, builder.ignoreGeneratedIndex);

这里的builder是默认实现的EventBusBuilder,它是一个工厂类

public class EventBusBuilder {
    private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();

    boolean logSubscriberExceptions = true;
    boolean logNoSubscriberMessages = true;
    boolean sendSubscriberExceptionEvent = true;
    boolean sendNoSubscriberEvent = true;
    boolean throwSubscriberException;
    boolean eventInheritance = true;
    boolean ignoreGeneratedIndex;
    boolean strictMethodVerification;
    ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;
    List<Class<?>> skipMethodVerificationForClasses;
    List<SubscriberInfoIndex> subscriberInfoIndexes;
    Logger logger;
    MainThreadSupport mainThreadSupport;

    EventBusBuilder() {
    }
....
}

通过这个可以看出,构造 subscriberMethodFinder时的参数为null,false,false。既然它的初始化已经完成,那么我们继续看findSubscriberMethods方法

List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
    //从缓存中取出订阅的方法,第一次时为null
    List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
    if (subscriberMethods != null) {
        return subscriberMethods;
    }
    //这个在构造中传入的为false
    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;
    }
}

在上面的注释中也写的很清楚了,这里重点看一下findUsingInfo方法

private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
    //FindState是SubscriberMethodFinder的内部类,用于辅助查找订阅方法
    FindState findState = prepareFindState();
    //初始话findState:   findState.clazz=subscriberClass,subscriberInfo=null
    findState.initForSubscriber(subscriberClass);
    while (findState.clazz != null) {
        //这里这个依然是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 {//通过反射查找
            findUsingReflectionInSingleClass(findState);
        }
        //继续在当前类的父类中查找
        findState.moveToSuperclass();
    }
    return getMethodsAndRelease(findState);
}

这里的查找主要是利用这个FindState辅助类

static class FindState {
    final List<SubscriberMethod> subscriberMethods = new ArrayList<>();
    final Map<Class, Object> anyMethodByEventType = new HashMap<>();
    final Map<String, Class> subscriberClassByMethodKey = new HashMap<>();
    final StringBuilder methodKeyBuilder = new StringBuilder(128);

    Class<?> subscriberClass;
    Class<?> clazz;
    boolean skipSuperClasses;
    SubscriberInfo subscriberInfo;

    void initForSubscriber(Class<?> subscriberClass) {
        this.subscriberClass = clazz = subscriberClass;
        skipSuperClasses = false;
        subscriberInfo = null;
    }
...}

findUsingInfo的前两行主要是初始话,然后在while循环中扫描当前class以及其父class,这里的findState.subscriberInfo为null它的具体查找代码如下

private SubscriberInfo getSubscriberInfo(FindState findState) {
    if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
        SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
        if (findState.clazz == superclassInfo.getSubscriberClass()) {
            return superclassInfo;
        }
    }
    if (subscriberInfoIndexes != null) {
        for (SubscriberInfoIndex index : subscriberInfoIndexes) {
            SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
            if (info != null) {
                return info;
            }
        }
    }
    return null;
}

因为在构造SubscriberMethodFinder时 subscriberInfoIndexes为null,初始话FindState时findState.subscriberInfo为null。所以最终的查找是通过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
        methods = findState.clazz.getMethods();
        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");
        }
    }
}

上面就是通过反射来查找当前类中使用的@Subscribe注解的public方法,并且将注解所标注的方法的名字,参数,注解值等信息保存在findState的subscriberMethods中。至此查找方法就结束了。我们再回到register方法中继续,也就是对每个方法进行subscribe

private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
    //这里的eventType为onEvent方法的参数类型
    Class<?> eventType = subscriberMethod.eventType;
    //创建一个新的订阅
    Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
    //从缓存中利用当前的参数拿到之前的订阅
    CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
    //如果没订阅就放到缓存中
    if (subscriptions == null) {
        subscriptions = new CopyOnWriteArrayList<>();
        subscriptionsByEventType.put(eventType, subscriptions);
    } else {
        if (subscriptions.contains(newSubscription)) {
            throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                    + eventType);
        }
    }

    int size = subscriptions.size();
    //根据优先级priority进行排序
    for (int i = 0; i <= size; i++) {
        if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
            subscriptions.add(i, newSubscription);
            break;
        }
    }
    //从缓存中取出当前类中所存储的所有onEvent方法的参数的集合
    List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
    if (subscribedEvents == null) {
        subscribedEvents = new ArrayList<>();
        typesBySubscriber.put(subscriber, subscribedEvents);
    }
    //将当前方法(onEvent)的参数类型添加到保存当前类(Activity等)的参数集合中(map的value)
    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();
                    checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                }
            }
        } else {
            Object stickyEvent = stickyEvents.get(eventType);
            checkPostStickyEventToSubscription(newSubscription, stickyEvent);
        }
    }
}

其实中段的本质就是将找到的方法存到本地的map中,以便于之后对消息的处理。到这里EventBus.getDefault().register()就结束了。因为register和unregister是成对使用的,那么我们就看一下他又做了什么事。

public synchronized void unregister(Object subscriber) {
    List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
    if (subscribedTypes != null) {
        for (Class<?> eventType : subscribedTypes) {
            unsubscribeByEventType(subscriber, eventType);
        }
        typesBySubscriber.remove(subscriber);
    } else {
        logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass());
    }
}

这里就很简单了就是将上面声明的那几个map中与当前类相关的信息删除。就是说register为add操作,unregister则为delete操作。接下来这是EventBus的使用了,就是它的post方法

public void post(Object event) {
    //构造postingState,它保存了事件队列和线程模式等信息
    PostingThreadState postingState = currentPostingThreadState.get();
    //这个queue初始化为空
    List<Object> eventQueue = postingState.eventQueue;
    eventQueue.add(event);
    //isPosting和isMainThread初始值均为false
    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;
        }
    }
}

这里需要看的就是postSingleEvent

private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
    Class<?> eventClass = event.getClass();
    boolean subscriptionFound = false;
    //该值在初始化时为true
    if (eventInheritance) {
        //查找当前事件类型的class,并且保存到集合中
        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);
    }
  ...
}

这里没什么好说的就是调用postSingleEventForEventType进行事件的发送,在这个方法里面会调用postToSubscription(subscription, event, postingState.isMainThread);进行真正的发送

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 {
                // 如果是在子线程发送事件,则将事件入队列,通过Handler切换到主线程执行处理事件
                // mainThreadPoster 不为空
                mainThreadPoster.enqueue(subscription, event);
            }
            break;
        // 无论在那个线程发送事件,都先将事件入队列,然后通过 Handler 切换到主线程,依次处理事件。
        // mainThreadPoster 不为空
        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);
    }
}

这里的case则是定义事件接收的线程,也就是onEvent方法中定义的订阅者所在的线程,这里的backgroundPoster,asyncPoster以及mainThreadPoster等都是用于线程切换的,其中最重要的是invokeSubscriber

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);
    }
}

就是利用反射调用方法。到这里非粘性事件的处理就结束了。从以上分析可以看出,从方法的扫描以及处理都用到了反射,如果大量的使用会影响性能,因此在本次分析的3.1.1版本中,该库已经引入了APT,在编译期生成文件,使得在运行期时扫描方法的时候不需要利用反射,只是在post方法中利用反射调用方法。同理也得从如何使用开始 在app/build.gradle中加入

android {
    ...
    defaultConfig {
     ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [eventBusIndex: 'com.mwy.test.messengerdemo.MyEventBusIndex']
            }
        }
    }
   ...
    }
}
dependencies {
    implementation 'org.greenrobot:eventbus:3.1.1'
    annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1'
    ...
}

build项目之后会生成MyEventBusIndex

public class MyEventBusIndex implements SubscriberInfoIndex {
    private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;

    static {
        SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();

        putIndex(new SimpleSubscriberInfo(MainActivity.class, true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onEvent", TestEvent.class),
            new SubscriberMethodInfo("onEvent", TestEvent2.class),
        }));

        putIndex(new SimpleSubscriberInfo(Main2Activity.class, true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("onEvent", TestEvent.class),
            new SubscriberMethodInfo("onEvent", TestEvent3.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;
        }
    }
}

这里面我是在MainActivity和Main2Activity中分别注册了TestEvent、TestEvent2和TestEvent,TestEvent3。也就是说整个项目中有多少class注册了EventBus,以及每个class中有多少个onEvent都会出现在这个类中。

在application中使用上面定义的MyEventBusIndex

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
    }
}

至此我们就可以采用编译期动态生成代码的方式了。 同样我们还是从使用开始 EventBus.builder()其实就是创建了一个默认的EventBusBuilder对象,与EventBus.getDefault中的builder对象是同一类型,紧接着会调用addIndex方法,他就是给EventBusBuilder中的subscriberInfoIndexes赋值,在默认的实现中通过上面的分析我们知道他是null,这里直接赋值了。既然是扫描方法的时候起作用,那么我们就重新看看fingUsingInfo这个方法,这里面会调用getSubscriberInfo,此时subscriberInfoIndexes不为null,所以直接就返回了这个info

上面的整个流程是完事了,但最重要的一个问题还没有说,那就是这个类是如何生成的。之前已经说过是利用APT(如果不明白如何使用的可以看我的上一篇文章),那么我们就看一下它是如何处理的。关键就是Processor


@SupportedAnnotationTypes("org.greenrobot.eventbus.Subscribe")
@SupportedOptions(value = {"eventBusIndex", "verbose"})
public class EventBusAnnotationProcessor extends AbstractProcessor {
    public static final String OPTION_EVENT_BUS_INDEX = "eventBusIndex";
    public static final String OPTION_VERBOSE = "verbose";

    /** Found subscriber methods for a class (without superclasses). */
    private final ListMap<TypeElement, ExecutableElement> methodsByClass = new ListMap<>();
    private final Set<TypeElement> classesToSkip = new HashSet<>();

    private boolean writerRoundDone;
    private int round;
    private boolean verbose;

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latest();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
        Messager messager = processingEnv.getMessager();
        ...
            //搜索有注解的方法
            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) {
            // IntelliJ does not handle exceptions nicely, so log and print a message
            e.printStackTrace();
            messager.printMessage(Diagnostic.Kind.ERROR, "Unexpected error in EventBusAnnotationProcessor: " + e);
        }
        return true;
    }

    private void collectSubscribers(Set<? extends TypeElement> annotations, RoundEnvironment env, Messager messager) {
        //遍历当前类中的Annotation,这里的Annotation是我们自己定义的支持的类型这里就是
        //@SupportedAnnotationTypes("org.greenrobot.eventbus.Subscribe")
        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);
                }
            }
        }
    }

   ....
    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) {
                    //Silent
                }
            }
        }
    }

    ...
}

其实上面最主要的就是那么几行,首先是扫描所有被@Subscribe注解的方法,并且将方法和所在的类保存到本地变量中,接着根据过滤条件剔除一些,最后开始写文件。