前言
EventBus的构造方法涉及到属性的初始化,以及一些重要参数的赋值、重要标志位的获取。
代码分析
1、EventBus构造
EventBus的构造采用单例模式中的双检锁/双重校验锁方式,这种方式是多线程安全的。代码如下所示:
static volatile EventBus defaultInstance;
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;
}
/**
* 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);
}
该单例模式的流程图如下所示:
可以看到具体的构造方法用到了new EventBus(),而与普通的单例模式不同的是构造方法前面用了public修饰。看注释可以知道这是提供给使用者生成多个对象准备的,而且每个对象的使用是互相独立的。当然一般情况下我们只是用getDefault()创建对象就足够了。
2、EventBusBuilder的分析
EventBus的构造方法最终是会调到EventBus(EventBusBuilder 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对象获取配置,EventBusBuilder采用的是建造者模式。而如果通过getDefault()方式获取EventBus对象的话,那么则会用系统默认创建的DEFAULT_BUILDER;
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
那么先分别看下EventBus(EventBusBuilder builder)中配置的意义,这也可以帮助理解后续其他部分代码:
1、三个Poster,用于后续的事件分发。backgroundPoster和asyncPoster直接new出一个对象出来,而mainThreadPoster的获取方式比较特殊,他是通过MainThreadSupport这个接口的内部类来实现的。MainThreadSupport最终也是调用HandlerPoster实现新建Poster的,也就是说MainThreadSupport充当了代理的功能。逻辑图如下所示:
2、subscriberMethodFinder 这个是注册的时候主要的方法,用于查询对应的Event等信息。
3、subscriberInfoIndexes 该变量为索引参数,用于后续采用索引或者反射的方式查询。
4、eventInheritance 该变量为判断是否考虑父类的情况
由上可知EventBusBuilder在构建的时候起着相当重要的作用。那么着重分析一下EventBusBuilder,先看下EventBusBuilder中定义的变量:
private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
boolean logSubscriberExceptions = true;
boolean logNoSubscriberMessages = true;
boolean sendSubscriberExceptionEvent = true;
boolean sendNoSubscriberEvent = true;
boolean throwSubscriberException;
boolean eventInheritance = true;
boolean ignoreGeneratedIndex;
boolean strictMethodVerification;
ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;
List<Class<?>> skipMethodVerificationForClasses;
List<SubscriberInfoIndex> subscriberInfoIndexes;
Logger logger;
MainThreadSupport mainThreadSupport;
再看下EventBusBuilder与其他类的被调用关系图如下所示:
OK,从上面的逻辑图可以看出EventBusBuilder在构造方法的时候提供参数配置的同时也提供了两个比较重要的功能:一个是newCachedThreadPool线程池,可用于AsyncExecutor调用。另一个就是installDefaultEventBus(),他用于重新注册默认的builder,他只能在获取对象之前调用,代码如下所示。
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.defaultInstance = build();
return EventBus.defaultInstance;
}
}
总结
1、首先通过Eventbus的构造过程可以了解后续注册以及事件方法所要用到的几个属性,对于功能会有个大概的预先了解。
2、MainThreadSupport以及EventBusBuilder的写法还不是特别理解。这边先过一遍,后续再深入理解。