这篇文章主要是根据我们平时的使用,一步一步的分析EventBus源码流程,因此分为三步:
1、注册订阅者
2、事件发布
3、反注册订阅者
1、register 注册订阅者
在使用eventBus的时候,第一个步骤就是注册订阅者
EventBus.getDefault().register(this);
getDefault方法是一个单例模式的初始化方法,主要就是获取一个实例,源码如下:
public static EventBus getDefault() {
EventBus instance = defaultInstance;
if (instance == null) {
synchronized (EventBus.class) {
instance = EventBus.defaultInstance;
if (instance == null) {
instance = EventBus.defaultInstance = new EventBus();
}
}
}
return instance;
}
可以很清楚的看到,这里只是一个DoubleCheck的单例模式,接下来直接看一下构造方法:
/**
* Creates a new EventBus instance; each instance is a separate scope in which events are delivered. To use a
* central bus, consider {@link #getDefault()}.
*/
public EventBus() {
this(DEFAULT_BUILDER);
}
EventBus(EventBusBuilder builder) {
logger = builder.getLogger();
subscriptionsByEventType = new HashMap<>();
typesBySubscriber = new HashMap<>();
stickyEvents = new ConcurrentHashMap<>();
mainThreadSupport = builder.getMainThreadSupport();
mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
backgroundPoster = new BackgroundPoster(this);
asyncPoster = new AsyncPoster(this);
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
//
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex);
logSubscriberExceptions = builder.logSubscriberExceptions;
logNoSubscriberMessages = builder.logNoSubscriberMessages;
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
throwSubscriberException = builder.throwSubscriberException;
eventInheritance = builder.eventInheritance;
executorService = builder.executorService;
}
构造方法里面是通过一个Builder模式来对EventBus各项配置进行初始化
在getDefault获取到实例之后,就会调用register方法进行注册,这时候进入register方法看一下注册过程:
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
//获取到订阅者中所有的订阅方法,并储存到list集合中
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
从源码里面看,注册过程只有两步:
a、根据注册时传入的订阅者对象,找到所有的订阅方法;
b、订阅所有的订阅方法
a1)、
首先看一下如何查找到订阅者中所有的订阅方法,即findSubscriberMethods()方法,subscriberMethodFinder是在EventBus构造方法中进行的初始化,进入findSubscriberMethods方法中进行查看:
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
//METHOD_CACHE 一个map集合,以订阅者为key,以订阅方法的list集合为value进行缓存
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
//如果当前的对象已经被缓存,则直接获取返回
if (subscriberMethods != null) {
return subscriberMethods;
}
if (ignoreGeneratedIndex) {
// 如果忽略索引,就根据反射来获取
subscriberMethods = findUsingReflection(subscriberClass);
} else {
//否则使用索引
subscriberMethods = findUsingInfo(subscriberClass);
}
//如果该订阅者中没有订阅方法,此处会抛出一个异常,提醒你该订阅者和他的父类里面都没有订阅方法