EventBus是一款基于发布/订阅事件总线。
简单的说,个人理解为:订阅者A委托EventBus进行注册,B发送Event消息的时候,EventBus遍历订阅者队列,找到订阅了Event的所有class,通过反射调用该class对应的method。
官网上给出的架构图如下:
EventBus使用三部曲
1.注册
EventBus.getDefault().register
首先看看注册时怎么进行,只抽出了代码逻辑的主要部分(删掉了部分细节代码),从大局观上了解其运行的方式。
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
subscribe(subscriber, subscriberMethod);
}
这里的subscriber即为订阅者,在EventBus类里面完成订阅
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
Class<?> eventType = subscriberMethod.eventType;
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
subscriptionsByEventType.put(eventType, subscriptions);
}
取出订阅者subscriber注解方法,包装成Subscription对象,该对象包含订阅者对象引用和注解方法method
2.post发送消息
public void post(Object event) {
PostingThreadState postingState = currentPostingThreadState.get();
List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);
if (!postingState.isPosting) {
postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();
postingState.isPosting = true;
if (postingState.canceled) {
throw new EventBusException("Internal error. Abort state was not reset");
}
try {
while (!eventQueue.isEmpty()) {
postSingleEvent(eventQueue.remove(0), postingState);
}
} finally {
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
详细步骤如下:
post
=>postSingleEvent(准备工作,处理是否取消发送,是否在主线程等)
=>postSingleEvent(装订订阅的方法)
=>postSingleEventForEventType(遍历发送消息至订阅者,含终止发送消息开关)
=>postToSubscription(线程调度相关)
=>invokeSubscriber
最终发送消息调用的方法,取到subscription订阅者的订阅函数,通过反射invoke调用该函数,并传递event对象
void invokeSubscriber(Subscription subscription, Object event) {
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
}
3.注销
EventBus.getDefault().unregister
unregister
=>unsubscribeByEventType
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions != null) {
int size = subscriptions.size();
for (int i = 0; i < size; i++) {
Subscription subscription = subscriptions.get(i);
if (subscription.subscriber == subscriber) {
subscription.active = false;
subscriptions.remove(i);
i--;
size--;
}
}
}
}
注销其实处理的事情很少,remove掉注册的订阅者,完成退订。