在EventBus3.0之后,事件处理的方法名可以随便取。但是需要添加一个注解@Subscribe,并且可以指定线程模型。
EventBus中的4种TreadMode(线程模型)
POSTING(默认):事件在哪个线程发布出来的,事件处理函数就会在哪个线程中运行。事件处理使用此模式必须避免执行耗时操作,以避免阻塞可能是主线程的发布线程。
MAIN:事件处理会在UI线程中执行。
BACKGROUND:如果事件本来就是在子线程中发布出来的,那么事件处理函数直接在发布事件的线程中执行。如果事件是在UI线程中发布出来的,使用一个后台线程,按顺序传递其所有事件。
ASYNC:无论事件在哪个线程中发布,都在单独的线程中调用事件处理方法。
事件的分发最终会调用postToSubscription对事件进行处理:
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 {
//将订阅事件添加到主线程队列
mainThreadPoster.enqueue(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);
}
}
mainThreadPoster继承自Handler,将订阅方法切换到主线程。backgroundPoster和asyncPoster继承自Runnable,将事件分发事件加入队列并提交任务到线程池执行,区别是backgroundPoster使用一个后台线程,按顺序传递其所有事件。
EventBus构造方法中创建了几个分发者:
EventBus(EventBusBuilder builder) {
...
mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
backgroundPoster = new BackgroundPoster(this);
asyncPoster = new AsyncPoster(this);
...
}