之前我们简单介绍了EventBus如何使用,这里从getDefault()方法当作切入点。正如我们我们所知道的,我们使用EventBus都是使用这个方法拿到实例的,可是有什么用:
/**
* Convenience singleton for apps using a process-wide EventBus instance.
*/
// 设立用的是单例模式
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;
}
// 理论上单例模式构造函数是私有的,这个是公开的
// EventBus并不是只有一条总线,还有其他的总线,订阅者可以订阅到不同的EventBus上,不同的EventBus发送数据是完全隔离开的
public EventBus() {
// 这个就是我们经常使用的,使用builder构造实例
this(DEFAULT_BUILDER);
}
// 很明显,这个是使用了构建者模式
EventBus(EventBusBuilder builder) {
logger = builder.getLogger();
// 这个以事件类型为key(可以理解成Event.class),subscription(封装的有订阅者),通过事件类型找到相关的订阅者
subscriptionsByEventType = new HashMap<>();
// 把订阅者当作key,事件当作value,当我们注册和注销的时候会用的到
typesBySubscriber = new HashMap<>();
// 维护者粘性事件
stickyEvents = new ConcurrentHashMap<>();
// 接下来就是EventBus中非常重要的三个Poster(同时队形这个threadMode)负责线程之间的调度
mainThreadSupport = builder.getMainThreadSupport();
mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
backgroundPoster = new BackgroundPoster(this);
asyncPoster = new AsyncPoster(this);
// 表示Event生成的索引值
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;
}
小结:这里用的是构建者模式创建的实例,下面会对其中的poster有介绍
// 调用HandlerPoster实例化
@Override
public Poster createPoster(EventBus eventBus) {
return new HandlerPoster(eventBus, looper, 10);
}
这是我们研究的重点
// 很明显,底层是通过handler来实现的(Poster 就是一个实现入队的接口方法)
public class HandlerPoster extends Handler implements Poster {
// 底层就是实现一个队列(存放事件)
private final PendingPostQueue queue;
// 事件在handler的handlerMessage存在的最大事件值
private final int maxMillisInsideHandleMessage;
private final EventBus eventBus;
// 标志handler是否运行起来
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) {
// PendingPost就不再列举,就是通过ArrayList获取和释放
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
queue.enqueue(pendingPost);
if (!handlerActive) {
handlerActive = true;
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();
// 开启循环,获取事件调用invokeSubscriber分发处理事件
while (true) {
PendingPost pendingPost = queue.poll();
if (pendingPost == null) {
synchronized (this) {
// Check again, this time in synchronized
pendingPost = queue.poll();
// 处理完毕,则handlerActive置为false,结束
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;
}
}
}
小结:就是通过handler,在handMessage中开启循环获取分发处理事件
// 很明显,实现入队列方法,我们要把主要目光放在实现的run方法之中
final class BackgroundPoster implements Runnable, Poster {
// 同样的队列(和mainThreadPoster是一致的)
private final PendingPostQueue queue;
private final EventBus eventBus;
private volatile boolean executorRunning;
// 初始化,获取需要的eventBus
BackgroundPoster(EventBus eventBus) {
this.eventBus = eventBus;
queue = new PendingPostQueue();
}
// 入队操作
public void enqueue(Subscription subscription, Object event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
queue.enqueue(pendingPost);
if (!executorRunning) {
executorRunning = true;
// 通过线程池执行操作(我们要接下来关注run方法)
eventBus.getExecutorService().execute(this);
}
}
}
// 同样是取出,循环取完为止(是放在线程池中执行的)
@Override
public void run() {
try {
try {
while (true) {
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;
}
}
}
小结:通过线程池,循环取出事件执行,取完为止,同样调用invokeSubscriber方法分发处理事件(这个方法接下来我会介绍)
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);
}
}
小结: 通过线程池分发处理一个事件
总结:这次的getDefault方法,最终要的就是三个Poster,他们线程调度处理后面会用到,主要明白其中三个Poster大概流程,构建者模式构建了哪几个中重要的变量即可。(后面的说明会用的到此处提到的重要变量和方法。