//Builder模式,在EventBusBuilder里面完成一些默认的初始化操作
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
public static EventBus getDefault() {
//通过DCL单例模式创建EventBus实例
}
public EventBus() {
this(DEFAULT_BUILDER);
}
EventBus(EventBusBuilder builder) {
//通过EventBusBuilder完成的初始化构造
}
register:根据订阅者类信息,查询对应的订阅方法信息,遍历注册订阅方法
public void register(Object subscriber) {
//根据订阅者的类名信息查询订阅方法
Class subscriberClass = subscriber.getClass();
List subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
//遍历并注册这些订阅方法
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
SubscriberMethod:封装了订阅方法的基本类型信息,即@Subscribe中所注解的内容
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;
}
findSubscriberMethods: 查询订阅者所有的订阅方法,三种查询方式:缓存,通过注解器索引,反射
//METHOD_CACHE缓存了订阅及其所有订阅方法
private static final Map, List> METHOD_CACHE = new ConcurrentHashMap<>();
List findSubscriberMethods(Class subscriberClass) {
//首先查找缓存
List subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
//ignoreGeneratedIndex默认为false,表示是否忽略注解生成器
if (ignoreGeneratedIndex) {
subscriberMethods = findUsingReflection(subscriberClass);//通过反射获取
} else {
subscriberMethods = findUsingInfo(subscriberClass);//通过注解的方式
}
if (subscriberMethods.isEmpty()) {//如果当前订阅者没有声明订阅方法,则抛出异常
} else {
//将订阅者及订阅方法存入缓存中
METHOD_CACHE.put(subscriberClass, subscriberMethods);
...
}
}
findUsingInfo:获取订阅者信息,并且对其父类进行向上查询,最后将所有订阅方法信息封装到subscriberMethods列表中返回
private List findUsingInfo(Class subscriberClass) {
FindState findState = prepareFindState();//通过对象池的方式复用FindState
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.clazz改为subscriberClass的父类Class,再进行遍历
findState.moveToSuperclass();
}
return getMethodsAndRelease(findState);//回收FindState对象到对象池中,并返回subscriberMethods列表
}
...
//实现对象池
private static final FindState[] FIND_STATE_POOL = new FindState[POOL_SIZE];// POOL_SIZE = 4;
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();
}
getSubscriberInfo:遍历订阅者索引,返回查找的订阅者的信息
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;
}
FindState 主要用来辅助存储订阅者信息
static class FindState {
final List subscriberMethods = new ArrayList<>();
final Map anyMethodByEventType = new HashMap<>();
final Map subscriberClassByMethodKey = new HashMap<>();
final StringBuilder methodKeyBuilder = new StringBuilder(128);
...
void moveToSuperclass() { ... }// 修改findState.clazz为subscriberClass的父类Class
}
findUsingReflection
//FindState主要用来辅助存储订阅者信息
private List findUsingReflection(Class subscriberClass) {
FindState findState = prepareFindState();//通过对象池的方式复用FindState
findState.initForSubscriber(subscriberClass);//初始化参数并将订阅者类信息导入
while (findState.clazz != null) {
findUsingReflectionInSingleClass(findState);//通过反射查询订阅者的订阅方法
// 将findState.clazz改为subscriberClass的父类Class,再进行遍历
findState.moveToSuperclass();
}
return getMethodsAndRelease(findState);//回收FindState对象到对象池中,并返回subscriberMethods列表
}
findUsingReflectionInSingleClass:通过反射查询订阅者的订阅方法
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
methods = findState.clazz.getMethods();
findState.skipSuperClasses = true;
}
for (Method method : methods) {
int modifiers = method.getModifiers();
//校验方法修饰属性,是否PUBLIC及MODIFIERS_IGNORE
// MODIFIERS_IGNORE = Modifier.ABSTRACT | Modifier.STATIC | BRIDGE | SYNTHETIC;
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)) {
//抛出异常
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
//抛出异常
}
}
}
subscribe:将订阅者和订阅方法封装成对象,并将相同事件类型的封装对象根据事件优先级封装到CopyOnWriteArrayList集合中,再将事件类型和CopyOnWriteArrayList封装到map集合中
Map
post:通过在ThreadLocal中封装一个事件队列,去添加和执行相应的事件
public void post(Object event) {
//在ThreadLocal中封装一个线程状态信息,里面包含一个事件队列
PostingThreadState postingState = currentPostingThreadState.get();
List
postSingleEvent
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
Class eventClass = event.getClass();
boolean subscriptionFound = false;
if (eventInheritance) {
//遍历查找它的父类添加到列表
List> 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);
}
... //找不到事件时异常处理 NoSubscriberEvent
}
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class eventClass) {
CopyOnWriteArrayList subscriptions;
synchronized (this) {
//获取对应的订阅者
subscriptions = subscriptionsByEventType.get(eventClass);
}
...
for (Subscription subscription : subscriptions) {
postingState.event = event;
postingState.subscription = subscription;
boolean aborted = false;
try {//通知订阅者
postToSubscription(subscription, event, postingState.isMainThread);
aborted = postingState.canceled;
} finally {
...//重置postingState属性
}
if (aborted)break;
}
...
}
postToSubscription:通知订阅者,对于不同线程发布消息会调用相应的线程事件队列去执行
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 {
//如果不是主线程,则加入到主线程执行队列中执行,mainThreadPoster继承自Handler
mainThreadPoster.enqueue(subscription, event);
}
break;
case MAIN_ORDERED:
if (mainThreadPoster != null) {
mainThreadPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
case BACKGROUND:
if (isMainThread) {
//如果不是后台线程,则加入到后台线程行队列中执行
backgroundPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
case ASYNC:
asyncPoster.enqueue(subscription, event);
break;
...
}
}
...
void invokeSubscriber(Subscription subscription, Object event) {
...
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
}
postSticky: 粘性事件会通过单独的stickyEvents集合进行存储,同时会在事件订阅的时候进行check post,继而实现粘性这一效果
public void postSticky(Object event) {
synchronized (stickyEvents) {
stickyEvents.put(event.getClass(), event);
//添加到粘性事件列表,在上述注册订阅方法时,会通过列表去通知信息
}
// Should be posted after it is putted, in case the subscriber wants to remove immediately
post(event);//发布通知,当前已经订阅的订阅者可以收到
}
...
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
...
if (subscriberMethod.sticky) {//处理粘性事件
if (eventInheritance) {
// 迭代所有事件可能会导致很多粘性事件的效率低下,因此应该更改数据结构以允许更有效的查找
Set, Object>> entries = stickyEvents.entrySet();
for (Map.Entry, 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);
}
}
}