美文网首页
阅读EventBus源码

阅读EventBus源码

作者: xandone | 来源:发表于2020-01-13 18:16 被阅读0次

    EventBus是一款基于发布/订阅事件总线。
    简单的说,个人理解为:订阅者A委托EventBus进行注册,B发送Event消息的时候,EventBus遍历订阅者队列,找到订阅了Event的所有class,通过反射调用该class对应的method。
    官网上给出的架构图如下:


    EventBus-Publish-Subscribe.png

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

    相关文章

      网友评论

          本文标题:阅读EventBus源码

          本文链接:https://www.haomeiwen.com/subject/lwjnactx.html