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注解的方法,并且将方法和所在的类保存到本地变量中,接着根据过滤条件剔除一些,最后开始写文件。