美文网首页
EventBus源码分析

EventBus源码分析

作者: 瓦雷 | 来源:发表于2019-02-19 21:13 被阅读0次
    问题1:EventBus可以创建多个实例吗?
    /**
         * Creates a new EventBus instance; each instance is a separate scope in which events are delivered. To use a
         * central bus, consider {@link #getDefault()}.
         */
        public EventBus() {
            this(DEFAULT_BUILDER);
        }
    

    这里会发现EventBus的构造方法是公有的,也就是说我们自己可以自己new一个EventBus的实例,当然EventBus也提供了EventBusBuilder供我们构造使用。这里特意把构造方法的注释放了上来,大概翻译一下吧。

    创建一个EventBus实例,每一个实例的事件传递都在自己的实例范围,如果想统一管理,可以使用getDefault()方法。
    这里通过注释我们就可以解释第五个问题了,当然只是从注释层面,EventBus是可以创建多个实例的,并且多个实例的发送的事件是互不干扰的

    再看下 findSubscriberMethods() 这个方法,会通过类对象的 class 去解析这个类中的所有 Subscribe 注解方法的所有属性值,一个注解方法对应一个 SubscriberMethod 对象,包括 threadMode,priority,sticky,eventType,methodString。

    2、源码分析

    首先来看register

     //subscriber 传入的就是当前注册的Activity
        public void register(Object subscriber) {
            Class<?> subscriberClass = subscriber.getClass();
            //查找传入的Activity中一共有多少个含有@Subscribe注解的监听方法,有几个@Subscribe注解subscriberMethods的size就为几
            List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
            synchronized (this) {
                for (SubscriberMethod subscriberMethod : subscriberMethods) {
                    // subsciber 对 List<SubscriberMethod> 中每个 SubscriberMethod 进行订阅
                    subscribe(subscriber, subscriberMethod);
                }
            }
        }
    

    说明下SubscriberMethod这个类,类中有个参数eventType指的就是事件类型,即调用post("eventType")方法中传入的参数,也是@Subscribe注解的接收数据的方法中的入参,以下是debug中日志信息,很好的说明了一切:

    image.png

    再来看看Subscription这个类,可以理解成订阅者信息类

    //指的是当前订阅者的类
    final Object subscriber;
    final SubscriberMethod subscriberMethod;
    

    考以下几个问题:

    对于同一个 Event,当前类对该对象使用了多个方法进行了多次订阅,那么如果该 Event 被发射的时候,当前类会如何调用这些方法?
    对于同一个 Event,父类对该对象进行了一次订阅,子类重写该订阅方法,那么如果该 Event 被发射的时候,父类子类当中会如何处理这些方法?

    1、会的
    2、会调用子类的,不会调用父类的

    注册完之后就需要做订阅操作,subscribe

    // Must be called in synchronized block
        private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
            Class<?> eventType = subscriberMethod.eventType;
            Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
            //说明1
            CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
            if (subscriptions == null) {
                subscriptions = new CopyOnWriteArrayList<>();
                subscriptionsByEventType.put(eventType, subscriptions);
            } else {
                if (subscriptions.contains(newSubscription)) {
                    throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                            + eventType);
                }
            }
    
            int size = subscriptions.size();
            for (int i = 0; i <= size; i++) {
                if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
                    subscriptions.add(i, newSubscription);
                    break;
                }
            }
            //说明2
            List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
            if (subscribedEvents == null) {
                subscribedEvents = new ArrayList<>();
                typesBySubscriber.put(subscriber, subscribedEvents);
            }
            subscribedEvents.add(eventType);
    
         // 省略 sticky 事件
    

    说明1中:subscriptionsByEventType 是一个Map<Class<?>, CopyOnWriteArrayList<Subscription>>类型,key是eventType,value是订阅者集合

    说明2中:typesBySubscriber 是一个Map<Object, List<Class<?>>>类型
    key为订阅者类,value为eventType集合,主要是在关闭界面时反注册的时候使用

    相关文章

      网友评论

          本文标题:EventBus源码分析

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