阅读EventBus源码

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掉注册的订阅者,完成退订。