EventBus.getDefault().register(this);
/**
* Registers the given subscriber to receive events. Subscribers must call {@link #unregister(Object)} once they
* are no longer interested in receiving events.
* <p/>
* Subscribers have event handling methods that must be annotated by {@link Subscribe}.
* The {@link Subscribe} annotation also allows configuration like {@link
* ThreadMode} and priority.
*/
public void register(Object subscriber) {
// 首先调用反射的这个getClass(),获取到Class的订阅对象
Class<?> subscriberClass = subscriber.getClass();
// 通过上面获取到的Class对象,找到订阅方法的集合,他是通过 findSubscriberMethods去找到的。最终会返回一个订阅者的集合。
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
// 从方法的缓存池当中去查找是否已经有了这个订阅者方法,如果有的话就把这个订阅者集合返回给我们
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;
}
}subscribe(subscriber, subscriberMethod); } }}
接下来看下findSubscriberMethods这个方法的源码:
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
// 从方法的缓存池当中去查找是否已经有了这个订阅者方法,如果有的话就把这个订阅者集合返回给我们
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;
}
}它的List当中存储的数据类型是SubscriberMethod这个对象,接下来我们来看下它的源码:
/** Used internally by EventBus and generated subscriber indexes. */
public class SubscriberMethod {
final Method method; // 订阅方法
final ThreadMode threadMode; // 线程的模式
final Class<?> eventType; // 事件的类型
final int priority; // 发送方法事件的优先级
final boolean sticky; // 是否为粘性事件的标志位判断
/** Used for efficient comparison */
String methodString; // 方法名String
public SubscriberMethod(Method method, Class<?> eventType, ThreadMode threadMode, int priority, boolean sticky) {
this.method = method;
this.threadMode = threadMode;
this.eventType = eventType;
this.priority = priority;
this.sticky = sticky;
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
} else if (other instanceof SubscriberMethod) {
checkMethodString();
SubscriberMethod otherSubscriberMethod = (SubscriberMethod)other;
otherSubscriberMethod.checkMethodString();
// Don't use method.equals because of http://code.google.com/p/android/issues/detail?id=7811#c6
return methodString.equals(otherSubscriberMethod.methodString);
} else {
return false;
}
}
private synchronized void checkMethodString() {
if (methodString == null) {
// Method.toString has more overhead, just take relevant parts of the method
StringBuilder builder = new StringBuilder(64);
builder.append(method.getDeclaringClass().getName());
builder.append('#').append(method.getName());
builder.append('(').append(eventType.getName());
methodString = builder.toString();
}
}
@Override
public int hashCode() {
return method.hashCode();
}
}这个类就是将我们EventBus使用当中的参数全部封装起来,就是总的一个包装类。
接着我们来看下上面提到的register当中的findSubscriberMethods方法的源码
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
// 从方法的缓存池当中去查找是否已经有了这个订阅者方法,如果有的话就把这个订阅者集合返回给我们
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;
}
}private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
// 用来保存找到这些进行注解过的方法以及它们的状态,它主要是保存状态用的
// 我们根据FindState这个对象,我们才能进行下面一步的判断,我们可以获取到订阅方法,以及订阅方法相关的注解信息等等。
FindState findState = prepareFindState();
// 主要用来做赋值操作的
findState.initForSubscriber(subscriberClass);
while (findState.clazz != 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);
}1 接下来我们看下 FindState 的定义
static class FindState { // 以下是三个重要的集合
// 保存所有订阅者方法的一个List
final List<SubscriberMethod> subscriberMethods = new ArrayList<>();
// 保存的类型是通过事件类型为key,而订阅方法为value
final Map<Class, Object> anyMethodByEventType = new HashMap<>();
// key是订阅方法,value是订阅者Class对象
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;
}
void recycle() {
subscriberMethods.clear();
anyMethodByEventType.clear();
subscriberClassByMethodKey.clear();
methodKeyBuilder.setLength(0);
subscriberClass = null;
clazz = null;
skipSuperClasses = false;
subscriberInfo = null;
}
boolean checkAdd(Method method, Class<?> eventType) {
// 2 level check: 1st level with event type only (fast), 2nd level with complete signature when required.
// Usually a subscriber doesn't have methods listening to the same event type.
Object existing = anyMethodByEventType.put(eventType, method);
if (existing == null) {
return true;
} else {
if (existing instanceof Method) {
if (!checkAddWithMethodSignature((Method) existing, eventType)) {
// Paranoia check
throw new IllegalStateException();
}
// Put any non-Method object to "consume" the existing Method
anyMethodByEventType.put(eventType, this);
}
return checkAddWithMethodSignature(method, eventType);
}
}
private boolean checkAddWithMethodSignature(Method method, Class<?> eventType) {
methodKeyBuilder.setLength(0);
methodKeyBuilder.append(method.getName());
methodKeyBuilder.append('>').append(eventType.getName());
String methodKey = methodKeyBuilder.toString();
Class<?> methodClass = method.getDeclaringClass();
Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass);
if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) {
// Only add if not already found in a sub class
return true;
} else {
// Revert the put, old class is further down the class hierarchy
subscriberClassByMethodKey.put(methodKey, methodClassOld);
return false;
}
}
void moveToSuperclass() {
if (skipSuperClasses) {
clazz = null;
} else {
clazz = clazz.getSuperclass();
String clazzName = clazz.getName();
/** Skip system classes, this just degrades performance. */
if (clazzName.startsWith("java.") || clazzName.startsWith("javax.") || clazzName.startsWith("android.")) {
clazz = null;
}
}
}
}2 再接下来看下prepareFindState(),是如何来帮助我们找到FindState对象的 ?
private FindState prepareFindState() {
synchronized (FIND_STATE_POOL) {
for (int i = 0; i < POOL_SIZE; i++) {
FindState state = FIND_STATE_POOL[i];
if (state != null) {
// 清空是为了以后再去复用它
FIND_STATE_POOL[i] = null;
return state;
}
}
}
return new FindState();
}
本文详细解析了EventBus中注册订阅者的过程,包括如何通过反射获取订阅方法、缓存订阅方法以及检查订阅方法的有效性等关键步骤。
482

被折叠的 条评论
为什么被折叠?



