要探究的几个问题
- 流程原理
- 发送的消息,如何做到线程切换
- 何为粘性事件,实现原理
- EventBus使用缺点
流程
1.通过register来注册方法
通过ConcurrentHashMap来存储方法,key为注册类,value为注册类中的方法
- 标注1为查找通过@Subscribe注解标注的方法
- 标注2将查找的方法缓存起来
2.post发送事件
在EventBus类中
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 MAIN_ORDERED:
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);
}
}
实现线程切换
这一步是真正的方法调用,通过反射
3.何为粘性事件
普通事件是必须先注册,才能发送成功,而粘性事件是将事件通过ConcurrentHashMap缓存起来,然后通过再发送
public void postSticky(Object event) {
synchronized (stickyEvents) {
stickyEvents.put(event.getClass(), event);
}
// Should be posted after it is putted, in case the subscriber wants to remove immediately
post(event);
}
其中stickyEvents
就是ConcurrentHashMap
不足之处
尽管EventBus简单解耦,但大量使用会造成程序的混乱