主流开源框架源码深刻了解第6篇——EventBus源码分析。(源码以3.1.1版为准)java
EventBus是一个Android事件发布/订阅轻量级框架,经过此框架能够解耦发布者和订阅者,能够简化Android的事件传递。事件传递既能够用于Android的四大组件间的通信,也能够用于异步线程和主线程通信。其最大的优势在于,代码简洁、使用简单以及将事件的发布和订阅充分的解耦。android
public class EventActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event1);
}
@Override
protected void onStart() {
super.onStart();
LogUtil.i("onStart1");
// 官方demo 注册事件在onStart中
EventBus.getDefault().register(this);
}
/**
* @Subscribe 订阅者方法
* 订阅者方法将在发布事件所在的线程中被调用。这是 默认的线程模式。事件的传递是同步的,
* 一旦发布事件,全部该模式的订阅者方法都将被调用。这种线程模式意味着最少的性能开销,
* 由于它避免了线程的切换。所以,对于不要求是主线程而且耗时很短的简单任务推荐使用该模式。
* 使用该模式的订阅者方法应该快速返回,以免阻塞发布事件的线程,这多是主线程。
* 注:POSTING 就是和发布事件 post 所在一个线程中,post为 主/子 线程POSTING就为 主/子 线程中
*/
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessageEventPosting(EventBean member) {
LogUtil.i(member.toString());
LogUtil.i("onMessageEventPosting(), current thread is " + Thread.currentThread().getName());
}
/**
* @Subscribe 订阅者方法
* 注:无论post发布事件在什么线程中,MAIN 都在主线程
*/
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEventMain(EventBean member) {
LogUtil.i(member.toString());
TextView viewById = (TextView) findViewById(R.id.tv_event1);
viewById.setText(member.toString());
ToastUtil.showShortToast(member.toString());
LogUtil.i("onMessageEventMain(), current thread is " + Thread.currentThread().getName());
}
/**
* @Subscribe 订阅者方法
* 订阅者方法将在主线程(UI线程)中被调用。所以,能够在该模式的订阅者方法中直接更新UI界面。
* 事件将先进入队列而后才发送给订阅者,因此发布事件的调用将当即返回。
* 这使得事件的处理保持严格的串行顺序。使用该模式的订阅者方法必须快速返回,以免阻塞主线程。
* 注:无论post发布事件在什么线程中,MAIN_ORDERED 也都在主线程,不过该模式事件是串行的,按前后顺序的
*/
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMessageEventMainOrdered(EventBean member) {
LogUtil.i("onMessageEventMainOrdered(), current thread is " + Thread.currentThread().getName());
}
/**
* @Subscribe 订阅者方法
* 注:post(发布者)若为子线程,则 BACKGROUND 则是于post同一子线程中,若post为主线程,则BACKGROUND为单独的后台线程
*/
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessageEventBackground(EventBean member) {
LogUtil.i("onMessageEventBackground(), current thread is " + Thread.currentThread().getName());
}
/**
* @Subscribe 订阅者方法
* 注:post(发布者)不管是在子线程仍是主线程,ASYNC 都会单开一个线程
*/
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessageEventAsync(EventBean member) {
LogUtil.i("onMessageEventAsync(), current thread is " + Thread.currentThread().getName());
}
@Override
protected void onStop() {
super.onStop();
LogUtil.i("onStop1");
// 官方demo 解绑事件在onStop中
EventBus.getDefault().unregister(this);
}
}
复制代码
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
// 方法一:EventBus.getDefault(),EventBus为应用提供便利的单例
public static EventBus getDefault() {
// 双重校验并加锁的单例模式
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
// 方法二:new EventBus(); ,建立一个新的EventBus实例;每一个实例都是传递事件的单独范围。要使用中央总线,请考虑使用#getDefault()方式。
public EventBus() {
this(DEFAULT_BUILDER);
}
复制代码
// EventBus类:
private static final Map<Class<?>, List<Class<?>>> eventTypesCache = new HashMap<>();
// 以Event事件为key,以subscriptions订阅者为value,所以当发送Event时可经过该hashmap找到订阅此事件的订阅者
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
// 以Subscriber订阅者为key,以types类型为value,所以当发送注册和反注册时都会操做此hashmap
private final Map<Object, List<Class<?>>> typesBySubscriber;
// 维护粘性事件,使用并发的hashmap保存
private final Map<Class<?>, Object> stickyEvents;
// 线程内部数据存储类,在指定的线程中存储数据,也只能在指定线程中获取到存储数据。
private final ThreadLocal<PostingThreadState> currentPostingThreadState = new ThreadLocal<PostingThreadState>() {
@Override
protected PostingThreadState initialValue() {
return new PostingThreadState();
}
};
// @Nullable
private final MainThreadSupport mainThreadSupport;
// @Nullable
private final Poster mainThreadPoster;
private final BackgroundPoster backgroundPoster;
private final AsyncPoster asyncPoster;
private final SubscriberMethodFinder subscriberMethodFinder;
private final ExecutorService executorService;
private final boolean throwSubscriberException;
private final boolean logSubscriberExceptions;
private final boolean logNoSubscriberMessages;
private final boolean sendSubscriberExceptionEvent;
private final boolean sendNoSubscriberEvent;
private final boolean eventInheritance;
private final int indexCount;
private final Logger logger;
EventBus(EventBusBuilder builder) {
// 日志打印
logger = builder.getLogger();
// 事件对应的 订阅者和订阅者方法集合映射的封装类 存储
subscriptionsByEventType = new HashMap<>();
// 注册的订阅者存储
typesBySubscriber = new HashMap<>();
// 粘性事件存储
stickyEvents = new ConcurrentHashMap<>();
mainThreadSupport = builder.getMainThreadSupport();
// Android主线程处理事件
mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
// Background事件发送者
backgroundPoster = new BackgroundPoster(this);
// 异步事件发送者
asyncPoster = new AsyncPoster(this);
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
// @Subscribe注解方法找寻器
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex);
// 标识1:当调用事件处理函数时,若发生了异常是否进行异常信息打印。默认true
logSubscriberExceptions = builder.logSubscriberExceptions;
// 标识2:当没有订阅者订阅该事件时,是否打印日志。默认true
logNoSubscriberMessages = builder.logNoSubscriberMessages;
// 标识3:当调用事件处理函数时,若发生了异常是否发送SubscriberExceptionEvent这个事件。默认true
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
// 标识4:当没有订阅者订阅该事件时,是否发送NoSubscriberEvent事件。默认true
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
// 标识5:是否抛出SubscriberException异常。默认false
throwSubscriberException = builder.throwSubscriberException;
// 标识6:与event有继承关系的是否都须要发送。默认true
eventInheritance = builder.eventInheritance;
// 执行服务线程池
executorService = builder.executorService;
}
复制代码
EventBus的成员属性中,咱们来简单看一下其很是重要的三个Poster:mainThreadPoster、backgroundPoster、asyncPostersegmentfault
// EventBusBuilder类:
MainThreadSupport getMainThreadSupport() {
if (mainThreadSupport != null) {
return mainThreadSupport;
} else if (Logger.AndroidLogger.isAndroidLogAvailable()) {
// 获取主线程Looper,正常状况不会为null
Object looperOrNull = getAndroidMainLooperOrNull();
return looperOrNull == null ? null :
// 初始化MainThreadSupport,其实是AndroidHandlerMainThreadSupport对象
new MainThreadSupport.AndroidHandlerMainThreadSupport((Looper) looperOrNull);
} else {
return null;
}
}
Object getAndroidMainLooperOrNull() {
try {
// 获取主线程Looper
return Looper.getMainLooper();
} catch (RuntimeException e) {
// 并非真正的功能性Android(例如,“ Stub!” Maven依赖项)
return null;
}
}
public interface MainThreadSupport {
boolean isMainThread();
Poster createPoster(EventBus eventBus);
class AndroidHandlerMainThreadSupport implements MainThreadSupport {
private final Looper looper;
public AndroidHandlerMainThreadSupport(Looper looper) {
// 初始化looper属性,此处就是上面传进来的主线程Looper
this.looper = looper;
}
@Override
public boolean isMainThread() {
// 判断是否为主线程
return looper == Looper.myLooper();
}
@Override
public Poster createPoster(EventBus eventBus) {
// 初始化HandlerPoster,实际是Handler子类
return new HandlerPoster(eventBus, looper, 10);
}
}
}
复制代码
从构造函数中mainThreadPoster初始化,其实是经过mainThreadSupport.createPoster(this),而mainThreadSupport经过分析,咱们能够了解其实是AndroidHandlerMainThreadSupport类的对象。所以经过调用其createPoster(this)方法最后返回了HandlerPoster。// 继承自Handler
public class HandlerPoster extends Handler implements Poster {
// PendingPostQueue队列,用于保存用于即将执行的,待发送的post队列
private final PendingPostQueue queue;
// 表示post事件能够最大的在HandlerMessage中存活时间。规定最大的运行时间,由于运行在主线程,不能阻塞主线程。
private final int maxMillisInsideHandleMessage;
private final EventBus eventBus;
// 标识Handler是否有效,便是否运行起来啦
private boolean handlerActive;
protected HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
// 此处传入经过调用createPoster(this)方法,
// 传入保存到AndroidHandlerMainThreadSupport成员属性的主线程looper。
// 所以HandlerPoster是主线程的Handler,用于将EventBus异步线程消息切换回主线程。
super(looper);
// 将createPoster(this),传入的this,即EventBus保存
this.eventBus = eventBus;
this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
queue = new PendingPostQueue();
}
// 消息入队,若此Handler已运行,则直接发送obtainMessage消息,最终回到下面的handleMessage中处理入队消息。
public void enqueue(Subscription subscription, Object event) {
// 根据传进来的参数封装PendingPost待处理post对象。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");
}
}
}
}
// Handler中最重要的方法就是handleMessage,全部的消息处理最后都会通过此方法。
@Override
public void handleMessage(Message msg) {
boolean rescheduled = false;
try {
long started = SystemClock.uptimeMillis();
// 无限循环
while (true) {
// 从队列中取出消息
PendingPost pendingPost = queue.poll();
// 双重判断并加锁,若pendingPost为null,则返回
if (pendingPost == null) {
synchronized (this) {
// Check again, this time in synchronized
pendingPost = queue.poll();
if (pendingPost == null) {
handlerActive = false;
return;
}
}
}
// 使用反射的方法调用订阅者的订阅方法,进行事件的分发。
eventBus.invokeSubscriber(pendingPost);
long timeInMethod = SystemClock.uptimeMillis() - started;
// 每次分发完事件都会从新比较一下处于此循环的时间,若大于最大设定值则返回
if (timeInMethod >= maxMillisInsideHandleMessage) {
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
rescheduled = true;
return;
}
}
} finally {
handlerActive = rescheduled;
}
}
}
复制代码
// 实现Runnable接口
final class BackgroundPoster implements Runnable, Poster {
private final PendingPostQueue queue;
private final EventBus eventBus;
// 标识此Runnable是否正在运行
private volatile boolean executorRunning;
BackgroundPoster(EventBus eventBus) {
// 初始化eventBus属性
this.eventBus = eventBus;
// 初始化待处理post队列
queue = new PendingPostQueue();
}
// 消息入队,若此Runnable正在运行,则经过eventBus获取其初始化时构造的线程池,执行当前任务,最终回到下面的run方法中。
public void enqueue(Subscription subscription, Object event) {
// 根据传进来的参数封装PendingPost待处理post对象。PendingPost的封装,使用了数据缓存池。
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
// 消息入队
queue.enqueue(pendingPost);
if (!executorRunning) {
executorRunning = true;
// 经过eventBus成员获取在EventBus构造方法中初始化的线程池,而后执行当前Runnable
eventBus.getExecutorService().execute(this);
}
}
}
@Override
public void run() {
try {
try {
while (true) {
// 双重判断并加锁,若pendingPost为null,则返回
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执行分发事件,此while循环会将队列中全部消息都取出,并分发。
eventBus.invokeSubscriber(pendingPost);
}
} catch (InterruptedException e) {
eventBus.getLogger().log(Level.WARNING, Thread.currentThread().getName() + " was interruppted", e);
}
} finally {
executorRunning = false;
}
}
}
复制代码
// 实现Runnable接口
class AsyncPoster implements Runnable, Poster {
private final PendingPostQueue queue;
private final EventBus eventBus;
AsyncPoster(EventBus eventBus) {
this.eventBus = eventBus;
queue = new PendingPostQueue();
}
// 消息入队,直接使用evnetBus中线程池执行当前Runnable,最终回到run方法中
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);
}
}
复制代码
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;
}
// 复用或者建立新的obtainPendingPost
static PendingPost obtainPendingPost(Subscription subscription, Object event) {
synchronized (pendingPostPool) {
int size = pendingPostPool.size();
if (size > 0) {
// 移除并获取最后一位PendingPost
PendingPost pendingPost = pendingPostPool.remove(size - 1);
// 重置成员属性值
pendingPost.event = event;
pendingPost.subscription = subscription;
pendingPost.next = null;
return pendingPost;
}
}
return new PendingPost(event, subscription);
}
// 释放PendingPost成员属性保存的值
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); } } } } 复制代码
// 注解的使用:@Subscribe(threadMode = ThreadMode.MAIN, sticky = false, priority = 2)
/**
* Java四大元注解:
* 1. @Target :用于描述注解的使用范围,也就是说使用了@Target去定义一个注解,那么能够决定定义好的注解能用在什么地方
* 内部值:ElementType[] value()数组, value值类型 ElementType枚举类型
* 元注解中的枚举值决定了,一个注解能够标记的范围
* TYPE : 只能用在类、接口、枚举类型上。
* FIELD :字段声明和枚举常量
* METHOD :只能用在方法声明上
* PARAMETER : 只能用在参数的声明上 【参数名】
* CONSTRUCTOR : 只能用在构造方法的声明上
* LOCAL_VARIABLE : 只能用在局部变量声明上
* ANNOTATION_TYPE :只能用在注解上
* PACKAGE :只能用在包上
* TYPE_PARAMETER : 参数类型【形式参数类型】
* TYPE_USE : 任何位置均可以
* 2. @Retention:用于描述一个注解存在的生命周期【源码,字节码文件,运行时】
* 内部值:RetentionPolicy value();非数组,意味着只能一个值
* 值类型:枚举值RetentionPolicy,几个值决定了几个状态。以下几个值:
* SOURCE :表示一个注解能够存在于源码中==>java的源码中
* CLASS :表示 一个注解能够在源码中,而且能够在字节码文件中
* RUNTIME :表示 一个注解能够在源码、字节码、及运行时期该注解都会存在
* 3. @Document :使用了该注解后,将自定义注解设置为文档说明内容,在生成javadoc时会将该注解加入到文档中。
* 4. @Inherited :用于标注一个父类的注解是否能够被子类继承,若是一个注解须要被其子类所继承,则在声明时直接使用@Inherited注解便可。若是没有写此注解,则没法被子类继承。
* 不是说注解与注解之间可否相互继承,而是说:一个类A被注解了,那么另一个类B,继承了A类,B类可以继承到A类中,的注解 (即被@Inherited注解过的注解)
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
// 线程模式:对应mainThreadPoster、backgroundPoster、asyncPoster这三个Poster
ThreadMode threadMode() default ThreadMode.POSTING; // 默认的POSTING,不管消息处于什么线程,都直接分发,不作线程切换
// 是不是粘性事件
boolean sticky() default false;
// 订户优先级影响事件传递的顺序。在同一传送线程ThreadMode中,优先级较高的订户将在优先级较低的其余订户以前接收事件。默认优先级为0。
// 注意:优先级不会影响具备不一样ThreadMode的订户之间发送的顺序!
int priority() default 0;
}
复制代码
// EventBus类:
public void register(Object subscriber) {
// 获取订阅者的Class对象
Class<?> subscriberClass = subscriber.getClass();
// 经过订户方法查找器(经过注解查找)找到订阅者里订阅方法的集合
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
// 遍历集合按个执行订阅
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
复制代码
注册方法中总共完成两件事情:1. 查找订阅方法集合 2. 遍历集合按个订阅数组
// 订阅方法对象
public class SubscriberMethod {
final Method method; // 订阅的方法
final ThreadMode threadMode; // 线程模式
final Class<?> eventType; // 事件类型:即咱们订阅方法的惟一参数,就是事件类型;同时也是post(T)的参数。
final int priority; // 优先级
final boolean sticky; // 是否为粘性事件
String methodString; // 用于有效比较,是否同一个订阅方法
}
// 订阅方法查找器
class SubscriberMethodFinder {
// 用于缓存订阅者和订阅者订阅方法集合
private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();
private static final int POOL_SIZE = 4;
// FindState数组,缓存大小为4
private static final FindState[] FIND_STATE_POOL = new FindState[POOL_SIZE];
// 查找订阅方法集合
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
// 先查找缓存
if (subscriberMethods != null) {
return subscriberMethods;
}
// 默认为0
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;
}
}
// FindState中间器,用于查找保存状态
static class FindState {
// 保存订阅方法
final List<SubscriberMethod> subscriberMethods = new ArrayList<>();
// 以事件类型为key,方法为value
final Map<Class, Object> anyMethodByEventType = new HashMap<>();
// 以方法为key,订阅者的Class对象为value
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() {
...
}
// 用来判断FindState的anyMethodByEventType map是否已经添加过以当前eventType为key的键值对,没添加过则返回true
boolean checkAdd(Method method, Class<?> eventType) {
...
}
// 移动到父类Class
void moveToSuperclass() {
...
}
}
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
// 准备FindState对象
FindState findState = prepareFindState();
// findState中间器初始化订阅者
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
// 获取subscriberInfo,默认为null。此方法会在【Subscriber 索引】详细讲解。
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);
}
// 转移到父类Class
findState.moveToSuperclass();
}
// 经过findState获取方法并缓存findState
return getMethodsAndRelease(findState);
}
// FindState的缓存大小为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();
}
// 在单个类中使用反射查找订阅方法
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
// 获取全部声明的方法
methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
// 获取订阅者中声明的public方法,跳过父类
methods = findState.clazz.getMethods();
findState.skipSuperClasses = true;
}
for (Method method : methods) {
// 得到方法的修饰符
int modifiers = method.getModifiers();
// 若是是public类型,但非abstract、static等
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
// 得到当前方法全部参数的类型
Class<?>[] parameterTypes = method.getParameterTypes();
// 若是当前方法只有一个参数
if (parameterTypes.length == 1) {
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
// 若是当前方法使用了Subscribe注解
if (subscribeAnnotation != null) {
// 获得该方法参数的类型
Class<?> eventType = parameterTypes[0];
// checkAdd()方法用来判断FindState的anyMethodByEventType map是否已经添加过以当前eventType为key的键值对,没添加过则返回true
if (findState.checkAdd(method, eventType)) {
// 获得Subscribe注解的threadMode属性值,即线程模式
ThreadMode threadMode = subscribeAnnotation.threadMode();
// 建立一个SubscriberMethod对象,并添加到subscriberMethods集合
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");
}
}
}
// 从findState中间件中获取订阅的方法集合,并释放findState中间件,最后将findState缓存到数组中
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;
}
}
复制代码
// EventBus类:
// 必须在同步块中调用
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
// 获得当前订阅了事件的方法的参数类型
Class<?> eventType = subscriberMethod.eventType;
// Subscription类保存了要注册的类对象以及当前的subscriberMethod
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
// subscriptionsByEventType是一个HashMap,保存了以eventType为key,Subscription对象集合为value的键值对
// 先查找subscriptionsByEventType是否存在以当前eventType为key的值
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
// 若是不存在,则建立一个subscriptions,并保存到subscriptionsByEventType
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
// '绑定订阅者、订阅方法和事件类型的集合,subscriptions真正的值,在下面for循环中根据订阅方法优先级添加'
subscriptionsByEventType.put(eventType, subscriptions);
} else {
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
// 添加上边建立的newSubscription对象到subscriptions中
int size = subscriptions.size();
for (int i = 0; i <= size; i++) {
// 按照优先级将订阅方法添加置subscriptions中,其实是保存到subscriptionsByEventType集合中
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
subscriptions.add(i, newSubscription);
break;
}
}
// typesBySubscribere也是一个HashMap,保存了以当前要注册类的对象为key,注册类中订阅事件的方法的参数类型的集合为value的键值对
// 查找是否存在对应的参数类型集合
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
// 不存在则建立一个subscribedEvents,并保存到typesBySubscriber
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
// 保存当前订阅了事件的方法的参数类型
subscribedEvents.add(eventType);
// 粘性事件相关的
if (subscriberMethod.sticky) {
// 判断事件的继承性,默认是true
if (eventInheritance) {
// 获取全部粘性事件并遍历,stickyEvents就是发送粘性事件时,保存了事件类型和对应事件
Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
for (Map.Entry<Class<?>, Object> entry : entries) {
Class<?> candidateEventType = entry.getKey();
// isAssignableFrom:断定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是不是其超类或超接口。若是是则返回 true;不然返回 false。
if (eventType.isAssignableFrom(candidateEventType)) {
// 获取粘性事件
Object stickyEvent = entry.getValue();
// 处理粘性事件
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, isMainThread());
}
}
// 粘性事件订阅者,在注册时,会及时收到事件,就是在注册后经过此方法将粘性事件及时发布的
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 {
// 若是是在子线程发送事件,则将事件入队列,经过Handler切换到主线程执行处理事件
mainThreadPoster.enqueue(subscription, event);
}
break;
case MAIN_ORDERED:
// 不管在那个线程发送事件,都先将事件入队列,而后经过 Handler 切换到主线程,依次处理事件。mainThreadPoster不会为null
if (mainThreadPoster != null) {
mainThreadPoster.enqueue(subscription, event);
} else {
// temporary: technically not correct as poster not decoupled from subscriber
invokeSubscriber(subscription, event);
}
break;
case BACKGROUND:
if (isMainThread) {
// 若是在主线程发送事件,则先将事件入队列,而后经过线程池依次处理事件
backgroundPoster.enqueue(subscription, event);
} else {
// 若是在子线程发送事件,则直接在发送事件的线程经过反射处理事件
invokeSubscriber(subscription, event);
}
break;
case ASYNC:
// 不管在那个线程发送事件,都将事件入队列,而后经过线程池处理。
asyncPoster.enqueue(subscription, event);
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
}
}
// 用反射来执行订阅事件的方法,这样发送出去的事件就被订阅者接收并作相应处理
void invokeSubscriber(Subscription subscription, Object event) {
try {
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
} catch (InvocationTargetException e) {
handleSubscriberException(subscription, event, e.getCause());
} catch (IllegalAccessException e) {
throw new IllegalStateException("Unexpected exception", e);
}
}
复制代码
// EventBus类:
// 发布的线程状态
final static class PostingThreadState {
final List<Object> eventQueue = new ArrayList<>(); // 事件队列
boolean isPosting; // 是否正在发布
boolean isMainThread; // 是否在主线程
Subscription subscription; // 订阅者和订阅方法封装类
Object event; // 事件
boolean canceled; // 取消标志位
}
// ThreadLocal使用方法很简单:get()和set(T)
// ThreadLocal内部维护一个静态内部类ThreadLocalMap。每一个Thread中都具有一个ThreadLocalMap,而ThreadLocalMap能够存储以ThreadLocal为key的键值对。
private final ThreadLocal<PostingThreadState> currentPostingThreadState = new ThreadLocal<PostingThreadState>() {
// initialValue方法,同一个线程使用ThreadLocal#get()方法时,只有第一次会调用,即同一个线程使用的PostingThreadState对象是同一个。
@Override
protected PostingThreadState initialValue() {
return new PostingThreadState();
}
};
// 1. 将给定事件发布到事件总线
public void post(Object event) {
// currentPostingThreadState其实是:ThreadLocal<PostingThreadState>
// Threadlocal而是一个线程内部的存储类,能够在指定线程内存储数据,数据存储之后,只有指定线程能够获得存储数据
// 所以,如果同一个线程,则postingState是惟一的,能够类比成单例。
PostingThreadState postingState = currentPostingThreadState.get();
List<Object> eventQueue = postingState.eventQueue;
// 将事件添加到事件队列中,即同一线程post发布的全部事件都在该队列中
eventQueue.add(event);
// 是否正在发布事件
if (!postingState.isPosting) {
// 是不是主线程
postingState.isMainThread = isMainThread();
// 正在发布
postingState.isPosting = true;
if (postingState.canceled) {
throw new EventBusException("Internal error. Abort state was not reset");
}
try {
// 将事件队列中全部事件,移除队列并发布
while (!eventQueue.isEmpty()) {
postSingleEvent(eventQueue.remove(0), postingState);
}
} finally {
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
// 1.1 发布单个事件
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
Class<?> eventClass = event.getClass();
boolean subscriptionFound = false;
// 判断事件的继承性,默认是true
if (eventInheritance) {
// 查找全部事件类型,包括父类和接口
List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);
int countTypes = eventTypes.size();
// 遍历Class集合,继续处理事件
for (int h = 0; h < countTypes; h++) {
Class<?> clazz = eventTypes.get(h);
// 经过postSingleEventForEventType方法返回的boolean值和subscriptionFound,进行或运算,subscriptionFound默认为false
subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
}
} else {
subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
}
// 若subscriptionFound为false,则证实没有订阅者订阅此事件
if (!subscriptionFound) {
if (logNoSubscriberMessages) {
logger.log(Level.FINE, "No subscribers registered for event " + eventClass);
}
if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
eventClass != SubscriberExceptionEvent.class) {
// 发送 '没有订阅者事件' 事件
post(new NoSubscriberEvent(this, event));
}
}
}
// 1.1.1 查找全部Class对象,包括超类和接口。
private static List<Class<?>> lookupAllEventTypes(Class<?> eventClass) {
synchronized (eventTypesCache) {
// 先查找缓存
List<Class<?>> eventTypes = eventTypesCache.get(eventClass);
// 缓存没有则遍历查找
if (eventTypes == null) {
eventTypes = new ArrayList<>();
Class<?> clazz = eventClass;
while (clazz != null) {
eventTypes.add(clazz); // 添加当前事件类型
// 获取当前事件类实现的全部接口,添加到事件类型集合中
addInterfaces(eventTypes, clazz.getInterfaces());
clazz = clazz.getSuperclass();
}
// 经过以事件Class类型位key,缓存跟此事件有关的全部事件
eventTypesCache.put(eventClass, eventTypes);
}
return eventTypes;
}
}
// 1.1.1.1 经过父接口递归,添加事件的父接口类型
static void addInterfaces(List<Class<?>> eventTypes, Class<?>[] interfaces) {
// 遍历当前事件类所实现的全部接口
for (Class<?> interfaceClass : interfaces) {
// 若事件集合不包含此接口,则添加,并获取接口的父接口,继续迭代
if (!eventTypes.contains(interfaceClass)) {
eventTypes.add(interfaceClass);
// 继续迭代
addInterfaces(eventTypes, interfaceClass.getInterfaces());
}
}
}
// 1.1.2 针对事件类型发布单个事件
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
CopyOnWriteArrayList<Subscription> subscriptions;
synchronized (this) {
// 经过事件类型,获取 订阅者和订阅者方法集合映射的封装类 集合
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
// 遍历subscriptions集合
for (Subscription subscription : subscriptions) {
postingState.event = event;
postingState.subscription = subscription;
boolean aborted = false;
try {
// 发布到订阅
postToSubscription(subscription, event, postingState.isMainThread);
aborted = postingState.canceled;
} finally {
// 重置postingState
postingState.event = null;
postingState.subscription = null;
postingState.canceled = false;
}
if (aborted) {
break;
}
}
return true;
}
return false;
}
// 1.1.2.1 最后发布到订阅者,根据线程模式,进行线程切换
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 {
// 若是是在子线程发送事件,则将事件入队列,经过Handler切换到主线程执行处理事件
mainThreadPoster.enqueue(subscription, event);
}
break;
case MAIN_ORDERED:
// 不管在那个线程发送事件,都先将事件入队列,而后经过 Handler 切换到主线程,依次处理事件。mainThreadPoster不会为null
if (mainThreadPoster != null) {
mainThreadPoster.enqueue(subscription, event);
} else {
// temporary: technically not correct as poster not decoupled from subscriber
invokeSubscriber(subscription, event);
}
break;
case BACKGROUND:
if (isMainThread) {
// 若是在主线程发送事件,则先将事件入队列,而后经过线程池依次处理事件
backgroundPoster.enqueue(subscription, event);
} else {
// 若是在子线程发送事件,则直接在发送事件的线程经过反射处理事件
invokeSubscriber(subscription, event);
}
break;
case ASYNC:
// 不管在那个线程发送事件,都将事件入队列,而后经过线程池处理。
asyncPoster.enqueue(subscription, event);
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
}
}
// 1.1.2.1.1 用反射来执行订阅事件的方法,这样发送出去的事件就被订阅者接收并作相应处理
void invokeSubscriber(Subscription subscription, Object event) {
try {
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
} catch (InvocationTargetException e) {
handleSubscriberException(subscription, event, e.getCause());
} catch (IllegalAccessException e) {
throw new IllegalStateException("Unexpected exception", e);
}
}
复制代码
总结:缓存
如果粘性事件,则先添加到粘性事件集合中,再发布事件:bash
// EventBus类:
public void postSticky(Object event) {
synchronized (stickyEvents) {
// 添加到粘性事件集合,以备事件发布以后,订阅该事件的订阅者注册该事件时,依旧可以及时收到该事件
// 具体可回顾【注册EventBus—register(this)--遍历集合按个订阅】部分,查看如何注册后便可及时收到粘性事件
stickyEvents.put(event.getClass(), event);
}
// 调用普通事件的发布方法,及时发布
post(event);
}
复制代码
// EventBus类:
// 从全部事件类中注销给定的订阅者
public synchronized void unregister(Object subscriber) {
// 获取订阅者订阅的全部事件
List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
// 遍历订阅类型集合,释放以前缓存的当前类中的Subscription
for (Class<?> eventType : subscribedTypes) {
unsubscribeByEventType(subscriber, eventType);
}
// 删除以subscriber为key的键值对,更新typesBySubscriber
typesBySubscriber.remove(subscriber);
} else {
logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass());
}
}
// 仅更新subscriptionsByEventType,而不更新typesBySubscriber
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
// 获得当前参数类型对应的Subscription集合
List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions != null) {
int size = subscriptions.size();
// 遍历Subscription集合
for (int i = 0; i < size; i++) {
Subscription subscription = subscriptions.get(i);
// 若是当前subscription对象对应的注册类对象 和 要取消注册的注册类对象相同,则删除当前subscription对象
if (subscription.subscriber == subscriber) {
subscription.active = false;
subscriptions.remove(i);
i--;
size--;
}
}
}
}
复制代码
总结:unregister中释放了typesBySubscriber、subscriptionsByEventType中缓存的资源。并发
EventBus主要是在项目运行时经过反射来查找订事件的方法信息,若是项目中有大量的订阅事件的方法,必然会对项目运行时的性能产生影响。其实除了在项目运行时经过反射查找订阅事件的方法信息,EventBus在3.0以后增长了注解处理器,在程序的编译时候,就能够根据注解生成相对应的代码,相对于以前的直接经过运行时反射,大大提升了程序的运行效率,可是在3.0默认的是经过反射去查找用@Subscribe标注的方法,来生成一个辅助的索引类来保存这些信息,这个索引类就是Subscriber Index,和 ButterKnife 的原理是相似的。框架
dependencies {
implementation 'org.greenrobot:eventbus:3.1.1'
// 引入注解处理器
annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1'
}
复制代码
android {
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
// 根据项目实际状况,指定辅助索引类的名称和包名
arguments = [ eventBusIndex : 'com.android.framework.CustomEventBusIndex' ]
}
}
}
...
复制代码
// CustomEventBusIndex此类由EventBus注解处理器,在项目编译阶段动态生成
EventBus.builder().addIndex(new CustomEventBusIndex()).installDefaultEventBus();
public class CustomEventBusIndex implements SubscriberInfoIndex {
// 保存当前注册类的 Class 类型和其中事件订阅方法的信息
private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;
static {
SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();
/*
* 添加订阅者信息索引——SimpleSubscriberInfo参数:
* subscriberClass:订阅者Class类
* shouldCheckSuperclass:是否检查父类Class
* methodInfos(数组):订阅方法数组
*
* SubscriberMethodInfo构造参数:1. 方法名 2. 方法惟一参数类型,即事件类型
*/
putIndex(new SimpleSubscriberInfo(com.android.framework.launch.activity.EventActivity1.class, true,
new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onMessageEventPosting", com.android.baselibrary.bean.EventBean.class),
new SubscriberMethodInfo("onMessageEventMain", com.android.baselibrary.bean.EventBean.class,
ThreadMode.MAIN, 2, false),
new SubscriberMethodInfo("onMessageEventMainOrdered", com.android.baselibrary.bean.EventBean.class,
ThreadMode.MAIN_ORDERED),
new SubscriberMethodInfo("onMessageEventBackground", com.android.baselibrary.bean.EventBean.class,
ThreadMode.BACKGROUND),
new SubscriberMethodInfo("onMessageEventAsync", com.android.baselibrary.bean.EventBean.class,
ThreadMode.ASYNC),
}));
}
private static void putIndex(SubscriberInfo info) {
SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);
}
@Override
public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {
SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);
if (info != null) {
return info;
} else {
return null;
}
}
}
复制代码
// EventBusBuilder类:
public EventBusBuilder addIndex(SubscriberInfoIndex index) {
if (subscriberInfoIndexes == null) {
subscriberInfoIndexes = new ArrayList<>();
}
subscriberInfoIndexes.add(index);
return this;
}
复制代码
// EventBusBuilder类:
public EventBus installDefaultEventBus() {
synchronized (EventBus.class) {
if (EventBus.defaultInstance != null) {
throw new EventBusException("Default instance already exists." +
" It may be only set once before it's used the first time to ensure consistent behavior.");
}
// 给默认的EventBus单例对象赋初值
EventBus.defaultInstance = build();
return EventBus.defaultInstance;
}
}
// EventBus类:
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
复制代码
即用当前EventBusBuilder对象建立一个 EventBus 实例,这样咱们经过EventBusBuilder配置的 SubscriberInfoIndex 也就传递到了EventBus实例中,而后赋值给EventBus的 defaultInstance成员变量。因此在 Application 中生成了 EventBus 的默认单例,这样就保证了在项目其它地方执行EventBus.getDefault()就能获得惟一的 EventBus 实例!EventBus(EventBusBuilder builder) {
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
// @Subscribe注解方法找寻器
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex);
}
// 注意此字段
private List<SubscriberInfoIndex> subscriberInfoIndexes;
SubscriberMethodFinder(List<SubscriberInfoIndex> subscriberInfoIndexes, boolean strictMethodVerification,
boolean ignoreGeneratedIndex) {
this.subscriberInfoIndexes = subscriberInfoIndexes;
this.strictMethodVerification = strictMethodVerification;
this.ignoreGeneratedIndex = ignoreGeneratedIndex;
}
复制代码
咱们在上面【查找订阅方法集合】部分提到过一个方法:getSubscriberInfo,此方法默认返回值为null,所以后面查找订阅方法为:运行期经过反射查找。而若配置了Subscriber索引,则getSubscriberInfo返回不为null:// SubscriberMethodFinder类:
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;
}
}
// 上一段代码中,咱们说过注意此字段,此时不为null
if (subscriberInfoIndexes != null) {
for (SubscriberInfoIndex index : subscriberInfoIndexes) {
// 根据注册类的 Class 类查找SubscriberInfo
SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
if (info != null) {
return info;
}
}
}
return null;
}
// index.getSubscriberInfo此方法就是addIndex传入的 CustomEventBusIndex实现的方法:
@Override
public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {
SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);
if (info != null) {
return info;
} else {
return null;
}
}
复制代码
所以,findUsingInfo方法中,无需再经过反射单个查找订阅方法。private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
FindState findState = prepareFindState();
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
findState.subscriberInfo = getSubscriberInfo(findState);
// 此时不为null
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);
}
复制代码
Subscriber Index 的核心就是项目编译时使用注解处理器生成保存事件订阅方法信息的索引类,而后项目运行时将索引类实例设置到 EventBus 中,这样当注册 EventBus 时,从索引类取出当前注册类对应的事件订阅方法信息,以完成最终的注册,避免了运行时反射处理的过程,因此在性能上会有质的提升。项目中能够根据实际的需求决定是否使用 Subscriber Index。异步
www.jianshu.com/p/d9516884d…async
...
注:如有什么地方阐述有误,敬请指正。期待您的点赞哦!!!