- EventBus是一个单例类
- 订阅者 订阅方法查找与注册
订阅方法查找
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
// 查找订阅类中对应的订阅方法集合
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
// 注册过程
subscribe(subscriber, subscriberMethod);
}
}
}
// #############查找订阅类对应的订阅方法集合#####################
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
// 此处使用到了缓存 用来缓存订阅方法
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
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 = prepareFindState();
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
findState.subscriberInfo = getSubscriberInfo(findState);
// 默认情况下不会走到if里面,会走到else里
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);
}
// ################反射获取订阅类对应的订阅方法################
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
// 通过反射获取到订阅方法集合
// getDeclaredMethod获取到任何访问权限的方法
methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
...
}
for (Method method : methods) {
int modifiers = method.getModifiers();
// 过滤特殊修饰符的方法,只保留了public修饰符的方法。
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
// 获取方法的参数类型
Class<?>[] parameterTypes = method.getParameterTypes();
// 对只有一个参数的方法进行处理
if (parameterTypes.length == 1) {
// 判断是否该方法上有对应的Subscirbe注解
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) {
// eventType参数类型
Class<?> eventType = parameterTypes[0];
if (findState.checkAdd(method, eventType)) {
// 注解参数ThreadMode
ThreadMode threadMode = subscribeAnnotation.threadMode();
// 将订阅方法的信息保存到findState中
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
}
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
// 异常
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
// 异常
}
}
}
- 到目前为止,已经通过反射的方式寻找到了订阅类对应的 订阅方法
- 订阅者注册
// Must be called in synchronized block
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
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();
for (int i = 0; i <= size; i++) {
// 根据订阅方法的优先级将订阅对象插入到订阅对象集合中
// 此处是具有相同参数类型的事件会排优先级。即相同事件的会有优先级一说
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
subscriptions.add(i, newSubscription);
break;
}
}
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
subscribedEvents.add(eventType);
if (subscriberMethod.sticky) {
if (eventInheritance) {
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();
// 从stickyEvent中取出黏性事件,将该事件类型的事件发送给当前订阅者
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
} else {
Object stickyEvent = stickyEvents.get(eventType);
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
}
private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
if (stickyEvent != null) {
postToSubscription(newSubscription, stickyEvent, Looper.getMainLooper() == Looper.myLooper());
}
}
总结:
1、EventBus的订阅过程分为两个步骤:
1. 查找过程
查找当前订阅类对应的订阅方法集合 将其缓存起来 (使用到了反射)
2. 注册过程
对于普通事件:就是将上一步查找的订阅方法集合进一步封装,保存在内存中,以供后续使用
对于黏性事件:进一步封装之后,还会从stickyEvents事件保存队列中取出该事件类型的事件发送给当前订阅者
2、由上面代码可知
订阅方法必须是public修饰的,并且订阅方法参数必须只有一个