1.ThreadMode定义了5种线程模式
/**
* Each subscriber method has a thread mode, which determines in which thread the method is to be called by EventBus.
* EventBus takes care of threading independently from the posting thread.
*
* @see EventBus#register(Object)
* @author Markus
* ok
*/
public enum ThreadMode {
/**
* Subscriber will be called directly in the same thread, which is posting the event. This is the default. Event delivery
* implies the least overhead because it avoids thread switching completely. Thus this is the recommended mode for
* simple tasks that are known to complete in a very short time without requiring the main thread. Event handlers
* using this mode must return quickly to avoid blocking the posting thread, which may be the main thread.
* 订阅者将在发布事件的同一线程中直接调用。 这是默认设置。 事件传递意味着最少的开销,因为它完全避免了线程切换。
* 因此,对于已知在很短的时间内完成而不需要主线程的简单任务,这是推荐的模式。 使用此模式的事件处理程序必须快速
* 返回以避免阻塞可能是主线程的发布线程。
*
* 默认的线程模式,在哪个线程发送事件就在对应线程处理事件,避免了线程切换,效率高。
*/
POSTING,
/**
* On Android, subscriber will be called in Android's main thread (UI thread). If the posting thread is
* the main thread, subscriber methods will be called directly, blocking the posting thread. Otherwise the event
* is queued for delivery (non-blocking). Subscribers using this mode must return quickly to avoid blocking the main thread.
* If not on Android, behaves the same as {@link #POSTING}.
* 在 Android 上,订阅者将在 Android 的主线程(UI 线程)中调用。
* 如果发帖线程是主线程,则直接调用订阅者方法,阻塞发帖线程。否则,事件将排队等待传递(非阻塞)。
* 使用这种模式的订阅者必须快速返回以避免阻塞主线程。 如果不是在 Android 上,则行为与 {@link #POSTING} 相同。
*
* 如在主线程(UI线程)发送事件,则直接在主线程处理事件;如果在子线程发送事件,则先将事件入队列,然后通过 Handler 切换到主线程,依次处理事件。
*/
MAIN,
/**
* On Android, subscriber will be called in Android's main thread (UI thread). Different from {@link #MAIN},
* the event will always be queued for delivery. This ensures that the post call is non-blocking.
* 在 Android 上,订阅者将在 Android 的主线程(UI 线程)中调用。 与 {@link #MAIN} 不同,事件将始终排队等待交付。 这确保了 post 调用是非阻塞的。
*
* 无论在哪个线程发送事件,都将事件加入到队列中,然后通过Handler切换到主线程,依次处理事件。
*/
MAIN_ORDERED,
/**
* On Android, subscriber will be called in a background thread. If posting thread is not the main thread, subscriber methods
* will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single
* background thread, that will deliver all its events sequentially. Subscribers using this mode should try to
* return quickly to avoid blocking the background thread. If not on Android, always uses a background thread.
* 在 Android 上,订阅者将在后台线程中调用。 如果发帖线程不是主线程,则将在发帖线程中直接调用订阅者方法。
* 如果发布线程是主线程,则 EventBus 使用单个后台线程,它将按顺序传递其所有事件。 使用这种模式的订阅者应该尝试快速返回以避免阻塞后台线程。
* 如果不是在 Android 上,则始终使用后台线程。
*
* 与ThreadMode.MAIN相反,如果在子线程发送事件,则直接在子线程处理事件;如果在主线程上发送事件,则先将事件入队列,然后通过线程池处理事件。
*/
BACKGROUND,
/**
* Subscriber will be called in a separate thread. This is always independent from the posting thread and the
* main thread. Posting events never wait for subscriber methods using this mode. Subscriber methods should
* use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number
* of long running asynchronous subscriber methods at the same time to limit the number of concurrent threads. EventBus
* uses a thread pool to efficiently reuse threads from completed asynchronous subscriber notifications.
*
* 订阅者将在单独的线程中调用。 这始终独立于发布线程和主线程。 使用此模式发布事件从不等待订阅者方法。
* 如果订阅者方法的执行可能需要一些时间,则应使用此模式,例如 用于网络访问。
* 避免同时触发大量长时间运行的异步订阅者方法以限制并发线程数。
* EventBus 使用线程池来有效地重用来自已完成的异步订阅者通知的线程。
*
* 与ThreadMode.MAIN_ORDERED相反,无论在哪个线程发送事件,都将事件加入到队列中,然后通过线程池执行事件
*/
ASYNC
}
2.Subscribe注解
@Documented
@Retention(RetentionPolicy.RUNTIME)// 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
@Target({ElementType.METHOD})// 作用在方法上
public @interface Subscribe {
// 指定事件订阅方法所在的线程模式,也就是决定订阅方法是在哪个线程,默认是POSTING模式
ThreadMode threadMode() default ThreadMode.POSTING;
/**
* If true, delivers the most recent sticky event (posted with
* {@link EventBus#postSticky(Object)}) to this subscriber (if event available).
* 如果为 true,则将最近的粘性事件(通过 {@link EventBus#postSticky(Object)} 发布)传递给该订阅者(如果事件可用)。
* 是否支持粘性事件
*/
boolean sticky() default false;
/** Subscriber priority to influence the order of event delivery.
* Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before
* others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of
* delivery among subscribers with different {@link ThreadMode}s! */
// 优先级,如果指定了优先级,则若干方法接收同一事件时,优先级高的方法会先接收到。
int priority() default 0;
}
3.SubscriberMethodInfo和Subscribe注解一一对应
public class SubscriberMethodInfo {
final String methodName;
final ThreadMode threadMode;
final Class<?> eventType;
final int priority;
final boolean sticky;
public SubscriberMethodInfo(String methodName, Class<?> eventType, ThreadMode threadMode,
int priority, boolean sticky) {
this.methodName = methodName;
this.threadMode = threadMode;
this.eventType = eventType;
this.priority = priority;
this.sticky = sticky;
}
public SubscriberMethodInfo(String methodName, Class<?> eventType) {
this(methodName, eventType, ThreadMode.POSTING, 0, false);
}
public SubscriberMethodInfo(String methodName, Class<?> eventType, ThreadMode threadMode) {
this(methodName, eventType, threadMode, 0, false);
}
}
4.SubscriberMethod和Subscribe注解一一对应
public class SubscriberMethod {
final Method method;//反射里边的
final ThreadMode threadMode;
final Class<?> eventType;
final int priority;
final boolean sticky;
/** Used for efficient comparison */
String methodString;
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();
}
}
5.Subscription订阅关系
final class Subscription {
final Object subscriber;//实例
final SubscriberMethod subscriberMethod;
/**
* Becomes false as soon as {@link EventBus#unregister(Object)} is called, which is checked by queued event delivery
* {@link EventBus#invokeSubscriber(PendingPost)} to prevent race conditions.
*/
volatile boolean active;
Subscription(Object subscriber, SubscriberMethod subscriberMethod) {
this.subscriber = subscriber;
this.subscriberMethod = subscriberMethod;
active = true;
}
@Override
public boolean equals(Object other) {
if (other instanceof Subscription) {
Subscription otherSubscription = (Subscription) other;
return subscriber == otherSubscription.subscriber
&& subscriberMethod.equals(otherSubscription.subscriberMethod);
} else {
return false;
}
}
@Override
public int hashCode() {
return subscriber.hashCode() + subscriberMethod.methodString.hashCode();
}
}
6.PendingPost
final class PendingPost {
private final static List<PendingPost> pendingPostPool = new ArrayList<PendingPost>();
Object event;
Subscription subscription;
PendingPost next;
//构造函数
private PendingPost(Object event, Subscription subscription) {
this.event = event;
this.subscription = subscription;
}
static PendingPost obtainPendingPost(Subscription subscription, Object event) {
synchronized (pendingPostPool) {
int size = pendingPostPool.size();
if (size > 0) {
PendingPost pendingPost = pendingPostPool.remove(size - 1);
pendingPost.event = event;
pendingPost.subscription = subscription;
pendingPost.next = null;
return pendingPost;
}
}
return new PendingPost(event, subscription);
}
static void releasePendingPost(PendingPost pendingPost) {
pendingPost.event = null;
pendingPost.subscription = null;
pendingPost.next = null;
synchronized (pendingPostPool) {
// Don't let the pool grow indefinitely
if (pendingPostPool.size() < 10000) {
pendingPostPool.add(pendingPost);
}
}
}
}
7.PendingPostQueue
final class PendingPostQueue {
private PendingPost head;
private PendingPost tail;
synchronized void enqueue(PendingPost pendingPost) {
if (pendingPost == null) {
throw new NullPointerException("null cannot be enqueued");
}
if (tail != null) {
tail.next = pendingPost;
tail = pendingPost;
} else if (head == null) {
head = tail = pendingPost;
} else {
throw new IllegalStateException("Head present, but no tail");
}
notifyAll();
}
synchronized PendingPost poll() {
PendingPost pendingPost = head;
if (head != null) {
head = head.next;
if (head == null) {
tail = null;
}
}
return pendingPost;
}
synchronized PendingPost poll(int maxMillisToWait) throws InterruptedException {
if (head == null) {
wait(maxMillisToWait);
}
return poll();
}
}
8.Poster
/**
* Posts events.
*
* @author William Ferguson
* ok
*/
interface Poster {
/**
* Enqueue an event to be posted for a particular subscription.
*
* @param subscription Subscription which will receive the event.
* @param event Event that will be posted to subscribers.
*/
void enqueue(Subscription subscription, Object event);
}
9.HandlerPoster
/*
* Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.greenrobot.eventbus;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
//mainThreadPoster为HandlerPoster, 具体分析下HandlerPoster
public class HandlerPoster extends Handler implements Poster {
private final PendingPostQueue queue;
private final int maxMillisInsideHandleMessage;//10 ms
private final EventBus eventBus;
private boolean handlerActive;
protected HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
super(looper);
this.eventBus = eventBus;
this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
queue = new PendingPostQueue();
}
public void enqueue(Subscription subscription, Object event) {
// 用subscription和event封装一个PendingPost对象
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
// 加入到队列中
queue.enqueue(pendingPost);
if (!handlerActive) {
handlerActive = true;
// sendMessage()发送处理事件的消息,handleMessage()方法将被执行,将子线程切换到主线程
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
}
}
}
@Override
public void handleMessage(Message msg) {
boolean rescheduled = false;
try {
long started = SystemClock.uptimeMillis();
// 遍历队列
while (true) {
PendingPost pendingPost = queue.poll();
if (pendingPost == null) {
synchronized (this) {
// Check again, this time in synchronized
// 出队列,取出PendingPost对象
pendingPost = queue.poll();
if (pendingPost == null) {
handlerActive = false;
return;
}
}
}
//在主线程处理事件
eventBus.invokeSubscriber(pendingPost);
long timeInMethod = SystemClock.uptimeMillis() - started;
//处理事件完了,大于10ms则重新取消息处理
if (timeInMethod >= maxMillisInsideHandleMessage) {//又发了次消息
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
rescheduled = true;
return;
}
}
} finally {
handlerActive = rescheduled;
}
}
}
10.BackgroundPoster
/**
* Posts events in background.
*
* @author Markus
* ok
*/
final class BackgroundPoster implements Runnable, Poster {
private final PendingPostQueue queue;
private final EventBus eventBus;
private volatile boolean executorRunning;
BackgroundPoster(EventBus eventBus) {
this.eventBus = eventBus;
queue = new PendingPostQueue();
}
public void enqueue(Subscription subscription, Object event) {
// 用subscription和event封装一个PendingPost对象
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
// 加入队列
queue.enqueue(pendingPost);
if (!executorRunning) {
executorRunning = true;
// 调用newCachedThreadPool线程池,执行任务 ???
eventBus.getExecutorService().execute(this);
}
}
}
@Override
public void run() {
try {
try {
// 循环队列
while (true) {
// 等待1秒,取出PendingPost对象
PendingPost pendingPost = queue.poll(1000);
if (pendingPost == null) {
synchronized (this) {
// Check again, this time in synchronized
pendingPost = queue.poll();
if (pendingPost == null) {
executorRunning = false;
return;
}
}
}
eventBus.invokeSubscriber(pendingPost);
}
} catch (InterruptedException e) {
eventBus.getLogger().log(Level.WARNING, Thread.currentThread().getName() + " was interruppted", e);
}
} finally {
executorRunning = false;
}
}
}
11.AsyncPoster
/**
* Posts events in background.
*
* @author Markus
* ok
*/
class AsyncPoster implements Runnable, Poster {
private final PendingPostQueue queue;
private final EventBus eventBus;
AsyncPoster(EventBus eventBus) {
this.eventBus = eventBus;
queue = new PendingPostQueue();
}
public void enqueue(Subscription subscription, Object event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
queue.enqueue(pendingPost);
eventBus.getExecutorService().execute(this);
}
@Override
public void run() {
PendingPost pendingPost = queue.poll();
if(pendingPost == null) {
throw new IllegalStateException("No pending post available");
}
eventBus.invokeSubscriber(pendingPost);
}
}
12.MainThreadSupport
/**
* Interface to the "main" thread, which can be whatever you like.
* Typically on Android, Android's main thread is used.
* ok
*/
public interface MainThreadSupport {
boolean isMainThread();
Poster createPoster(EventBus eventBus);
class AndroidHandlerMainThreadSupport implements MainThreadSupport {
private final Looper looper;//主线程looper
public AndroidHandlerMainThreadSupport(Looper looper) {
this.looper = looper;
}
@Override
public boolean isMainThread() {
return looper == Looper.myLooper();
}
@Override
public Poster createPoster(EventBus eventBus) {
return new HandlerPoster(eventBus, looper, 10);
}
}
}
13.SubscriberInfo
/** Base class for generated index classes created by annotation processing. */
//ok
public interface SubscriberInfo {
Class<?> getSubscriberClass();
SubscriberMethod[] getSubscriberMethods();
SubscriberInfo getSuperSubscriberInfo();
boolean shouldCheckSuperclass();
}
14.AbstractSubscriberInfo
/** Base class for generated subscriber meta info classes created by annotation processing. */
public abstract class AbstractSubscriberInfo implements SubscriberInfo {
private final Class subscriberClass;
private final Class<? extends SubscriberInfo> superSubscriberInfoClass;
private final boolean shouldCheckSuperclass;
protected AbstractSubscriberInfo(Class subscriberClass, Class<? extends SubscriberInfo> superSubscriberInfoClass,
boolean shouldCheckSuperclass) {
this.subscriberClass = subscriberClass;
this.superSubscriberInfoClass = superSubscriberInfoClass;
this.shouldCheckSuperclass = shouldCheckSuperclass;
}
@Override
public Class getSubscriberClass() {
return subscriberClass;
}
@Override
public SubscriberInfo getSuperSubscriberInfo() {//??todo 干哈的
if(superSubscriberInfoClass == null) {
return null;
}
try {
return superSubscriberInfoClass.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public boolean shouldCheckSuperclass() {
return shouldCheckSuperclass;
}
protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType) {
return createSubscriberMethod(methodName, eventType, ThreadMode.POSTING, 0, false);
}
protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType, ThreadMode threadMode) {
return createSubscriberMethod(methodName, eventType, threadMode, 0, false);
}
protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType, ThreadMode threadMode,
int priority, boolean sticky) {
try {
Method method = subscriberClass.getDeclaredMethod(methodName, eventType);
return new SubscriberMethod(method, eventType, threadMode, priority, sticky);
} catch (NoSuchMethodException e) {
throw new EventBusException("Could not find subscriber method in " + subscriberClass +
". Maybe a missing ProGuard rule?", e);
}
}
}
15.SimpleSubscriberInfo
public class SimpleSubscriberInfo extends AbstractSubscriberInfo {
private final SubscriberMethodInfo[] methodInfos;
public SimpleSubscriberInfo(Class subscriberClass, boolean shouldCheckSuperclass, SubscriberMethodInfo[] methodInfos) {
super(subscriberClass, null, shouldCheckSuperclass);
this.methodInfos = methodInfos;
}
//通过methodInfos获取SubscriberMethod
@Override
public synchronized SubscriberMethod[] getSubscriberMethods() {
int length = methodInfos.length;
SubscriberMethod[] methods = new SubscriberMethod[length];
for (int i = 0; i < length; i++) {
SubscriberMethodInfo info = methodInfos[i];
methods[i] = createSubscriberMethod(info.methodName, info.eventType, info.threadMode,
info.priority, info.sticky);
}
return methods;
}
}
16.SubscriberInfoIndex
public interface SubscriberInfoIndex {
SubscriberInfo getSubscriberInfo(Class<?> subscriberClass);
}
17.SubscriberMethodFinder
class SubscriberMethodFinder {
//region 参数
/*
* In newer class files, compilers may add methods. Those are called bridge or synthetic methods.
* EventBus must ignore both. There modifiers are not public but defined in the Java class file format:
* http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.6-200-A.1
*/
private static final int BRIDGE = 0x40;
private static final int SYNTHETIC = 0x1000;
private static final int MODIFIERS_IGNORE = Modifier.ABSTRACT | Modifier.STATIC | BRIDGE | SYNTHETIC;
//subscriberClass 方法
private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();
private static final int POOL_SIZE = 4;
//干哈的??
private static final FindState[] FIND_STATE_POOL = new FindState[POOL_SIZE];
private final boolean strictMethodVerification;//严格方法检查,默认false,public, non-static, and non-abstract,一个参数
private final boolean ignoreGeneratedIndex;//忽略生成的index,默认false
//注解处理器生成的SubscriberInfoIndex
private final List<SubscriberInfoIndex> subscriberInfoIndexes;
//endregion
//region ok 构造函数
SubscriberMethodFinder(List<SubscriberInfoIndex> subscriberInfoIndexes, boolean strictMethodVerification,
boolean ignoreGeneratedIndex) {
this.subscriberInfoIndexes = subscriberInfoIndexes;//注解处理器生成的SubscriberInfoIndex
this.strictMethodVerification = strictMethodVerification;//false
this.ignoreGeneratedIndex = ignoreGeneratedIndex;//false
}
//endregion
static void clearCaches() {
METHOD_CACHE.clear();
}
//endregion
//region ok findSubscriberMethods
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
//先从缓存里面读取,订阅者的 Class
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
// ignoreGeneratedIndex属性表示是否忽略注解器生成的MyEventBusIndex。
// ignoreGeneratedIndex的默认值为false,可以通过EventBusBuilder来设置它的值
if (ignoreGeneratedIndex) {
// 利用反射来获取订阅类中所有订阅方法信息
subscriberMethods = findUsingReflection(subscriberClass);
} else {
// 从注解器生成的MyEventBusIndex类中获得订阅类的订阅方法信息
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;
}
}
//region findUsingInfo
//从注解器生成的MyEventBusIndex类中获得订阅类的订阅方法信息 // 使用apt提前解析的订阅者信息
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
// FindState 涉及到 享元设计模式
FindState findState = prepareFindState();
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
//遍历subscriberInfoIndexes里的 SubscriberInfoIndex,
//如果其getSubscriberInfo(findState.clazz)
//不为null则返回得到的SubscriberInfo
findState.subscriberInfo = getSubscriberInfo(findState);
if (findState.subscriberInfo != null) {
//得到所有的SubscriberMethod
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();
}
// 释放 findState 享元模式
return getMethodsAndRelease(findState);
}
//endregion
private SubscriberInfo getSubscriberInfo(FindState findState) {
if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
//这个时候,clazz代表父类,getSuperSubscriberInfo得到父类的SubscriberInfo的class刚好是clazz
//则直接返回
SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
if (findState.clazz == superclassInfo.getSubscriberClass()) {
return superclassInfo;
}
}
//遍历subscriberInfoIndexes里的 SubscriberInfoIndex,如果其getSubscriberInfo(findState.clazz)
//不为null则返回得到的SubscriberInfo
if (subscriberInfoIndexes != null) {
for (SubscriberInfoIndex index : subscriberInfoIndexes) {
SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
if (info != null) {
return info;
}
}
}
return null;
}
//region ok getMethodsAndRelease prepareFindState clearCaches
//享元模式本质就是将大量的相似的对象的公共的不会变化的部分抽象出来,作为静态变量,作为全局唯一的对象,让所有的对象共同使用这一组对象,达到节约内存的目的。
private List<SubscriberMethod> getMethodsAndRelease(FindState findState) {
List<SubscriberMethod> subscriberMethods = new ArrayList<>(findState.subscriberMethods);
findState.recycle();
synchronized (FIND_STATE_POOL) {
for (int i = 0; i < POOL_SIZE; i++) {
if (FIND_STATE_POOL[i] == null) {
FIND_STATE_POOL[i] = findState;
break;
}
}
}
return subscriberMethods;
}
//从FindState[]数组缓存里取一个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();
}
//endregion
// 利用反射来获取订阅类中所有订阅方法信息
private List<SubscriberMethod> findUsingReflection(Class<?> subscriberClass) {
FindState findState = prepareFindState();
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
// 寻找某个类中的所有事件响应方法
findUsingReflectionInSingleClass(findState);
findState.moveToSuperclass();//继续寻找当前类父类中注册的事件响应方法
}
return getMethodsAndRelease(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
try {
// 通过反射来获取订阅类的所有方法
methods = findState.clazz.getMethods();
} catch (LinkageError error) { // super class of NoClassDefFoundError to be a bit more broad...
String msg = "Could not inspect methods of " + findState.clazz.getName();
if (ignoreGeneratedIndex) {
msg += ". Please consider using EventBus annotation processor to avoid reflection.";
} else {
msg += ". Please make this class visible to EventBus annotation processor to avoid reflection.";
}
throw new EventBusException(msg, error);
}
//出现异常的时候skipSuperClasses设置为true
findState.skipSuperClasses = true;
}
// for 循环所有方法
for (Method method : methods) {
// 获取方法访问修饰符
int modifiers = method.getModifiers();
// 找到所有声明为 public 的方法,并且不是忽略的方法
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
Class<?>[] parameterTypes = method.getParameterTypes();// 获取参数的的 Class
if (parameterTypes.length == 1) {// 只允许包含一个参数
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) {
// 获取事件的 Class ,也就是方法参数的 Class
Class<?> eventType = parameterTypes[0];
// 检测添加
if (findState.checkAdd(method, eventType)) {
// 获取 ThreadMode
ThreadMode threadMode = subscribeAnnotation.threadMode();
// 往集合里面添加 SubscriberMethod ,解析方法注解所有的属性
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");
}
}
}
static class FindState {
//region 参数
//订阅方法集合,这里是最后返回的
final List<SubscriberMethod> subscriberMethods = new ArrayList<>();
//eventtype对应的方法
final Map<Class, Object> anyMethodByEventType = new HashMap<>();
//methdkey对应的订阅者
final Map<String, Class> subscriberClassByMethodKey = new HashMap<>();
final StringBuilder methodKeyBuilder = new StringBuilder(128);
//当前订阅者的类
Class<?> subscriberClass;
//当前查找的类
Class<?> clazz;//父类,初始化的时候就是subscriberClass
//是否跳过父类查找
boolean skipSuperClasses;
SubscriberInfo subscriberInfo;//订阅者信息
//endregion
//region initForSubscriber recycle
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;
}
//endregion
//region checkAdd()方法用来判断FindState中是否已经添加过将该事件类型为key的键值对,没添加过则返回true
//处理两种情况
//一.假如注册了3个方法,方法名不一样afun1 afun2 afun3,都添加
//二.子类覆盖了父类的订阅方法,只保留子类的
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.
// 1.检查eventType是否已经注册过对应的方法(一般都没有)
Object existing = anyMethodByEventType.put(eventType, method);
if (existing == null) {
// 第一种是判断当前类中是否已经有这个EventType和对应的订阅方法,一般一个类不会有对同
// 一个EventType写多个方法,会直接返回true,进行保存。
//如果没有,则返回true
return true;
} else {
// 2. 如果已经有方法注册了这个eventType
// 但是如果出现了同一个类中同样的EventType写了多个方法,该如何处理?
//a.1 假如注册了3个方法,方法名不一样afun1 afun2 afun3
//a.7 afun3 的时候existing 对象不是method了
//b.1 子类bfun_child,父类也注册了bfun_parent
if (existing instanceof Method) {
//这里步骤的意义在于往subscriberClassByMethodKey map里加入第一个方法
//a.2 existing是以前的方法afun1
//b.2 传入以前的方法bfun_child
if (!checkAddWithMethodSignature((Method) existing, eventType)) {
// Paranoia check
throw new IllegalStateException();
}
// Put any non-Method object to "consume" the existing Method
//a.4 anyMethodByEventType eventType设置了个不是Method的对象
//b.4 anyMethodByEventType eventType设置了个不是Method的对象
anyMethodByEventType.put(eventType, this);
}
//a.5 传入现在的方法afun2
//a.8 传入现在的方法afun3
//b.5 传入现在的方法bfun_parent
return checkAddWithMethodSignature(method, eventType);
}
}
private boolean checkAddWithMethodSignature(Method method, Class<?> eventType) {
// 以[方法名>eventType]为Key
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);
//a.3 传入以前的方法afun1,methodClassOld为null,并保存到了subscriberClassByMethodKey afun1->key,返回true
//b.3 传入以前的方法bfun_child,methodClassOld为null,并保存到了subscriberClassByMethodKey bfun_child->key,返回true
//a.6 传入现在的方法afun2,methodClassOld为null,并保存到了subscriberClassByMethodKey afun2->key,返回true
//b.6 传入现在的方法bfun_parent,methodClassOld为子类,methodClass为父类
//a.8 传入现在的方法afun3,methodClassOld为null,并保存到了subscriberClassByMethodKey afun3->key,返回true
// 对于同一类中同样的EventType写了多个方法,因为方法名不同,所以[方法名>eventType]的Key不同,
// methodClassOld会为null,直接返回 true。所以这种情况会将所有相同EventType的方法都进行保存。
// 对于子类重写父类方法的情况,则methodClassOld(即子类)不为null,并且methodClassOld也不是methodClass的父类,
// 所以会返回false。即对于子类重写父类订阅方法,只会保存子类的订阅方法,忽略父类的订阅方法。
// isAssignableFrom()方法是判断是否为某个类的父类,instanceof关键字是判断是否某个类的子类。
//b.7 传入现在的方法bfun_parent,methodClassOld为子类,methodClass为父类
//isAssignableFrom判断是否为某个类的父类
if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) {
// Only add if not already found in a sub class
return true;
} else {
// 这次根据 方法名>参数名进行完整校验,因为同一个类中同名同参的函数是不存在的,而同名不同参的在前一步已经被过滤了,
// 所以这里确保在一个类中不会重复注册.
// 但如果子类重写父类的方法的话,就会出现相同的methodKey。这时EventBus会做一次验证,
// 并保留子类的订阅信息。由于扫描是由子类向父类的顺序,故此时应当保留methodClassOld而忽略methodClass。如果代码上的注释 Revert the put
//b.8 传入现在的方法bfun_parent,methodClassOld为子类,methodClass为父类,subscriberClassByMethodKey保存子类的,返回false,不保存
// Revert the put, old class is further down the class hierarchy
subscriberClassByMethodKey.put(methodKey, methodClassOld);
return false;
}
}
//endregion
//region moveToSuperclass
void moveToSuperclass() {
if (skipSuperClasses) {
clazz = null;
} else {
clazz = clazz.getSuperclass();
String clazzName = clazz.getName();
// Skip system classes, this degrades performance.
// Also we might avoid some ClassNotFoundException (see FAQ for background).
if (clazzName.startsWith("java.") || clazzName.startsWith("javax.") ||
clazzName.startsWith("android.") || clazzName.startsWith("androidx.")) {
clazz = null;
}
}
}
//endregion
}
}