EventBus源码详解(一)——订阅过程

  1. EventBus是一个单例类
  2. 订阅者 订阅方法查找与注册
    订阅方法查找
public void register(Object subscriber) {
        Class<?> subscriberClass = subscriber.getClass();
        // 查找订阅类中对应的订阅方法集合 
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
        synchronized (this) {
                // 注册过程
                subscribe(subscriber, subscriberMethod);
            }
        }
    }

// #############查找订阅类对应的订阅方法集合#####################
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
        // 此处使用到了缓存    用来缓存订阅方法
        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
        if (subscriberMethods != null) {
            return subscriberMethods;
        }

        if (ignoreGeneratedIndex) {
            subscriberMethods = findUsingReflection(subscriberClass);
        } else {
            // 找到订阅方法集合
            subscriberMethods = findUsingInfo(subscriberClass);
        }
        if (subscriberMethods.isEmpty()) {
            throw new EventBusException("Subscriber " + subscriberClass
                    + " and its super classes have no public methods with the @Subscribe annotation");
        } else {
            METHOD_CACHE.put(subscriberClass, subscriberMethods);
            return subscriberMethods;
        }
    }

// 查找订阅方法集合 
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
        FindState findState = prepareFindState();
        findState.initForSubscriber(subscriberClass);
        while (findState.clazz != null) {
            findState.subscriberInfo = getSubscriberInfo(findState);
            // 默认情况下不会走到if里面,会走到else里
            if (findState.subscriberInfo != null) {
                SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
                for (SubscriberMethod subscriberMethod : array) {
                    if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
                        findState.subscriberMethods.add(subscriberMethod);
                    }
                }
            } else {
                findUsingReflectionInSingleClass(findState);
            }
            findState.moveToSuperclass();
        }
        return getMethodsAndRelease(findState);
    }

// ################反射获取订阅类对应的订阅方法################
    private void findUsingReflectionInSingleClass(FindState findState) {
        Method[] methods;
        try {
            // 通过反射获取到订阅方法集合
            // getDeclaredMethod获取到任何访问权限的方法
            methods = findState.clazz.getDeclaredMethods();
        } catch (Throwable th) {
            ...
        }
        for (Method method : methods) {
            int modifiers = method.getModifiers();
            // 过滤特殊修饰符的方法,只保留了public修饰符的方法。
            if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
                // 获取方法的参数类型
                Class<?>[] parameterTypes = method.getParameterTypes();
                // 对只有一个参数的方法进行处理
                if (parameterTypes.length == 1) {
                    // 判断是否该方法上有对应的Subscirbe注解
                    Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
                    if (subscribeAnnotation != null) {
                        // eventType参数类型
                        Class<?> eventType = parameterTypes[0];
                        if (findState.checkAdd(method, eventType)) {
                            // 注解参数ThreadMode
                            ThreadMode threadMode = subscribeAnnotation.threadMode();
                            // 将订阅方法的信息保存到findState中
                            findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                    subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                        }
                    }
                } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
                    // 异常
                }
            } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
                   // 异常
            }
        }
    }
  1. 到目前为止,已经通过反射的方式寻找到了订阅类对应的 订阅方法
  2. 订阅者注册
 // Must be called in synchronized block
    private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
        Class<?> eventType = subscriberMethod.eventType;
        // 创建订阅对象
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
        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;
            }
        }

        List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
        if (subscribedEvents == null) {
            subscribedEvents = new ArrayList<>();
            typesBySubscriber.put(subscriber, subscribedEvents);
        }
        subscribedEvents.add(eventType);

        if (subscriberMethod.sticky) {
            if (eventInheritance) {
                Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
                for (Map.Entry<Class<?>, Object> entry : entries) {
                    Class<?> candidateEventType = entry.getKey();
                    if (eventType.isAssignableFrom(candidateEventType)) {
                        Object stickyEvent = entry.getValue();
                        // 从stickyEvent中取出黏性事件,将该事件类型的事件发送给当前订阅者
                        checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                    }
                }
            } else {
                Object stickyEvent = stickyEvents.get(eventType);
                checkPostStickyEventToSubscription(newSubscription, stickyEvent);
            }
        }
    }

    private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
        if (stickyEvent != null) {
            postToSubscription(newSubscription, stickyEvent, Looper.getMainLooper() == Looper.myLooper());
        }
    }

总结:
1、EventBus的订阅过程分为两个步骤:
1. 查找过程
查找当前订阅类对应的订阅方法集合 将其缓存起来 (使用到了反射)
2. 注册过程
对于普通事件:就是将上一步查找的订阅方法集合进一步封装,保存在内存中,以供后续使用
对于黏性事件:进一步封装之后,还会从stickyEvents事件保存队列中取出该事件类型的事件发送给当前订阅者
2、由上面代码可知
订阅方法必须是public修饰的,并且订阅方法参数必须只有一个

猜你喜欢

转载自blog.csdn.net/reuxfhc/article/details/80691558
今日推荐