EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。
部分源码:
//通过反射,获取到订阅者的所有方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
String methodName = method.getName();
//只找以onEvent开头的方法
if (methodName.startsWith(eventMethodName)) {
int modifiers = method.getModifiers();
//判断订阅者是否是public的,并且是否有修饰符,看来订阅者只能是public的,并且不能被final,static等修饰
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
//获得订阅函数的参数
Class<?>[] parameterTypes = method.getParameterTypes();
//看了参数的个数只能是1个
if (parameterTypes.length == 1) {
//获取onEvent后面的部分
String modifierString = methodName.substring(eventMethodName.length());
ThreadMode threadMode;
if (modifierString.length() == 0) {
//订阅函数为onEvnet
//记录线程模型为PostThread,意义就是发布事件和接收事件在同一个线程执行,详细可以参考我对于四个订阅函数不同点分析
threadMode = ThreadMode.PostThread;
} else if (modifierString.equals("MainThread")) {
//对应onEventMainThread
threadMode = ThreadMode.MainThread;
} else if (modifierString.equals("BackgroundThread")) {
//对应onEventBackgrondThread
threadMode = ThreadMode.BackgroundThread;
} else if (modifierString.equals("Async")) {
//对应onEventAsync
threadMode = ThreadMode.Async;
} else {
if (skipMethodVerificationForClasses.containsKey(clazz)) {
continue;
} else {
throw new EventBusException("Illegal onEvent method, check for typos: " + method);
}
}
//获取参数类型,其实就是接收事件的类型
Class<?> eventType = parameterTypes[0];
methodKeyBuilder.setLength(0);
methodKeyBuilder.append(methodName);
methodKeyBuilder.append('>').append(eventType.getName());
String methodKey = methodKeyBuilder.toString();
if (eventTypesFound.add(methodKey)) {
// Only add if not already found in a sub class
//封装一个订阅方法对象,这个对象包含Method对象,threadMode对象,eventType对象
subscriberMethods.add(new SubscriberMethod(method, threadMode, eventType));
}
}
} else if (!skipMethodVerificationForClasses.containsKey(clazz)) {
Log.d(EventBus.TAG, "Skipping method (not public, static or abstract): " + clazz + "."
+ methodName);
}
}
}
//看了还会遍历父类的订阅函数
clazz = clazz.getSuperclass();
}
//最后加入缓存,第二次使用直接从缓存拿
if (subscriberMethods.isEmpty()) {
throw new EventBusException("Subscriber " + subscriberClass + " has no public methods called "
+ eventMethodName);
} else {
synchronized (methodCache) {
methodCache.put(key, subscriberMethods);
}
return subscriberMethods;
}
}