美文网首页
Eventbus 3.1.1 源码解析(一)

Eventbus 3.1.1 源码解析(一)

作者: LouisXWB | 来源:发表于2019-03-03 23:37 被阅读0次

    1、简介

    Eventbus在项目中已经接入一段时间了,它是一个 Android 事件发布/订阅框架,作用是为了简化 Android 的事件传递。具体来说,就是它简化了 Android 组件之间的通信,包括四大组件之间、主线程与异步线程之间的通信,同时也解耦了发布者和订阅者的关系,避免了复杂、容易出错的依赖关系和生命周期问题。

    下面通过Eventbus的基本使用方法开始,逐步深入对源码进行分析,让自己对这个框架有更深入的理解。

    2、简介和基本使用

    它主要由四个部分组成,发布者订阅者事件事件传递

    EventBus 关系图

    2.1 定义事件

    我们需要提前定义事件Event的实体类,具体传递什么参数自己定义:

    public static class MessageEvent { /* Additional fields if needed */ }
    

    2.2 注册、解注册订阅者

    很简单,我们只需要在订阅事件的地方,通过Eventbus进行注册即可:

    EventBus.getDefault().register(this);
    

    register是强引用,如果没有解注册,那么强引用会让对象一直被持有而无法回收,导致内存泄露,必须在不需要接收事件时取消注册:

    EventBus.getDefault().unregister(this);
    

    2.3 订阅事件

    在需要接收事件的地方声明订阅方法,可以指定响应的线程类型、订阅方法的优先级和粘性,后面会具体分析:

    @Subscribe(threadMode = ThreadMode.MAIN)  
    public void onMessageEvent(MessageEvent event) {/* Do something */};
    

    2.4 发送事件

    EventBus的post方法用于发送事件:

    EventBus.getDefault().post(new MessageEvent());
    

    还支持发送粘性事件:

    EventBus.getDefault().postSticky(new MessageEvent());
    

    3、分析源码

    3.1 EventBus getDefault()

    通过懒汉模式获取EventBus实例:

    /** Convenience singleton for apps using a process-wide EventBus instance. */
        public static EventBus getDefault() {
            EventBus instance = defaultInstance;
            if (instance == null) {
                synchronized (EventBus.class) {
                    instance = EventBus.defaultInstance;
                    if (instance == null) {
                        instance = EventBus.defaultInstance = new EventBus();
                    }
                }
            }
            return instance;
        }
    

    如果不存在,则通过构造函数来初始化实例,传入的DEFAULT_BUILDER是一个默认创建好的EventBusBuilder实例,它包含了创建EventBus实例的一系列自定义参数,通过它我们就可以自定义自己的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(EventBusBuilder builder) {
            logger = builder.getLogger();
            //日志处理器,默认为android.util.Log,也可以自己设置其他的日志处理器
            subscriptionsByEventType = new HashMap<>();
           //Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType
           //key为事件的类型,value是所有订阅该事件的List集合
            typesBySubscriber = new HashMap<>();
            // Map<Object, List<Class<?>>> typesBySubscriber
            //订阅者对应订阅事件的集合,key是订阅者,value是订阅者订阅的事件集合
            stickyEvents = new ConcurrentHashMap<>();
            //保存粘性事件的集合
            mainThreadSupport = builder.getMainThreadSupport();
            // 主线程接口,可以自定义,默认是Android定义的主线程
            mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
            //主线程发送器
            backgroundPoster = new BackgroundPoster(this);
            //后台线程发送器
            asyncPoster = new AsyncPoster(this);
            //异步线程发送器
            indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
            //索引数量,为了提高优化性能,3.0以后提供索引,后面再详细介绍
            subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
                    builder.strictMethodVerification, builder.ignoreGeneratedIndex);
            //用于查找订阅者方法 
            logSubscriberExceptions = builder.logSubscriberExceptions;
            //是否打印订阅者调用订阅函数异常的日志,默认为true
            logNoSubscriberMessages = builder.logNoSubscriberMessages;
            //是否打印没有订阅者订阅事件的日志,默认为true
            sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
            //订阅者调用订阅函数异常时,是否发送SubscriberExceptionEvent事件,默认为true
            sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
            //没有订阅者订阅事件事,是否发送NoSubscriberEvent事件,默认为true
            throwSubscriberException = builder.throwSubscriberException;
            //是否抛出SubscriberException异常,默认为false
            eventInheritance = builder.eventInheritance;
            //是否支持事件继承,默认为 true
            executorService = builder.executorService;
            //线程池
        }
    

    3.2 EventBus register(Object subscriber)

    注册订阅者,如果需要订阅事件,必须通过调用register(Object subscriber)方法来注册,才可接收到目标事件

    /**
         * Registers the given subscriber to receive events. Subscribers must call {@link #unregister(Object)} once they
         * are no longer interested in receiving events.
         * <p/>
         * Subscribers have event handling methods that must be annotated by {@link Subscribe}.
         * The {@link Subscribe} annotation also allows configuration like {@link
         * ThreadMode} and priority.
         */
        public void register(Object subscriber) {
            Class<?> subscriberClass = subscriber.getClass();
            //找到订阅者类
            List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
            //通过传入的订阅者类,找到订阅者的所有订阅方法
            synchronized (this) {
                for (SubscriberMethod subscriberMethod : subscriberMethods) {
                    subscribe(subscriber, subscriberMethod);
                }
            }
        }
    

    关于SubscriberMethod,它包含了订阅者方法的一些参数,只在内部给Eventbus和生成的索引来使用,这些参数在编写订阅者方法时就可以自定义:

    /** Used internally by EventBus and generated subscriber indexes. */
    public class SubscriberMethod {
        final Method method ;//订阅方法
        final ThreadMode threadMode;//订阅方法响应的线程
        final Class<?> eventType;//订阅的事件类型
        final int priority;//优先级
        final boolean sticky;//是否为粘性
        /** Used for efficient comparison */
        String methodString;//方法的描述
    }
    

    3.2.1 SubscriberMethodFinder findSubscriberMethods(Class<?> subscriberClass)

    SubscriberMethodFinder: 查找订阅方法的类
    List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass):查找订阅者所有的订阅方法

    List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
           List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
           //Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();
           //获取订阅者对应的订阅方法集合的缓存
           if (subscriberMethods != null) {
               //缓存不为null则直接返回
               return subscriberMethods;
           }
           
           //ignoreGeneratedIndex:是否忽略注解器生成的索引(索引后面会介绍)
           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");
               //找不到则抛出”no public methods with the @Subscribe annotation“异常
           } else {
               METHOD_CACHE.put(subscriberClass, subscriberMethods);
               //将订阅者-订阅者方法放进缓存的map集合METHOD_CACHE
               return subscriberMethods;
           }
       }
    

    内部获取订阅者方法的实现有两种

    • findUsingReflection(Class<?> subscriberClass)
    • findUsingInfo(Class<?> subscriberClass)
      第一种:findUsingReflection(Class<?> subscriberClass)
    private List<SubscriberMethod> findUsingReflection(Class<?> subscriberClass) {
            FindState findState = prepareFindState();
            findState.initForSubscriber(subscriberClass);
            //初始化保存和校验订阅方法的类FindState
            while (findState.clazz != null) {
                //通过反射获取订阅方法
                findUsingReflectionInSingleClass(findState);
                //查找订阅者的父类
                findState.moveToSuperclass();
            }
            //返回查找到的订阅方法集合
            return getMethodsAndRelease(findState);
        }
    
    //用于订阅方法的保存和校验
    class FindState {
            final List<SubscriberMethod> subscriberMethods = new ArrayList<>();
            final Map<Class, Object> anyMethodByEventType = new HashMap<>();
            final Map<String, Class> subscriberClassByMethodKey = new HashMap<>();
            final StringBuilder methodKeyBuilder = new StringBuilder(128);
            boolean checkAdd(Method method, Class<?> eventType){...}
            boolean checkAddWithMethodSignature(Method method, Class<?> eventType) {...}
            void moveToSuperclass() {...}
    }
    

    FindState:用于订阅方法的保存和校验
    通过SubscriberMethodFinder的prepareFindState()方法获得:

    //FindState[] FIND_STATE_POOL = new FindState[POOL_SIZE];
    //int POOL_SIZE = 4;
    //FIND_STATE_POOL为FindState的缓存池,FindState就可循环利用,避免重复创建过多对象,节省内存。
    private FindState prepareFindState() {
            synchronized (FIND_STATE_POOL) {
                for (int i = 0; i < POOL_SIZE; i++) {
                    FindState state = FIND_STATE_POOL[i];
                    if (state != null) {
                        FIND_STATE_POOL[i] = null;
                        return state;
                    }
                }
            }
            return new FindState();
        }
    

    接下来我们看看如何通过反射获取订阅方法
    void findUsingReflectionInSingleClass(FindState findState)

    private void findUsingReflectionInSingleClass(FindState findState) {
            Method[] methods;
            try {
                // This is faster than getMethods, especially when subscribers are fat classes like Activities
                methods = findState.clazz.getDeclaredMethods();
            } catch (Throwable th) {
                // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
                methods = findState.clazz.getMethods();
                findState.skipSuperClasses = true;
            }
            //利用反射获取方法集合
            //遍历方法
            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) {
                        //通过@Subscribe 注解获得Subscribe注解
                        Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
                        if (subscribeAnnotation != null) {
                            Class<?> eventType = parameterTypes[0];
                            //校验方法
                            if (findState.checkAdd(method, eventType)) {
                                //解析注解的线程类型
                                ThreadMode threadMode = subscribeAnnotation.threadMode();
                                //创建订阅方法对象,并保存至findState的subscriberMethods集合
                                findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                        subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                            }
                        }
                    } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
                        String methodName = method.getDeclaringClass().getName() + "." + method.getName();
                        throw new EventBusException("@Subscribe method " + methodName +
                                "must have exactly 1 parameter but has " + parameterTypes.length);
                    }
                } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
                    String methodName = method.getDeclaringClass().getName() + "." + method.getName();
                    throw new EventBusException(methodName +
                            " is a illegal @Subscribe method: must be public, non-static, and non-abstract");
                }
            }
        }
    

    我们已经一步步了解完如何通过反射获取订阅方法集合,接下来我们要讲第二种获取订阅方法的方式,通过索引获取订阅方法:findUsingInfo(Class<?> subscriberClass)

    我们先了解一下索引是什么?

    Eventbus3.0之前使用的是运行时注解,获取订阅方法都是通过java的反射机制,而java的反射机制是非常耗费性能的,详细可见这篇文章# java反射的性能问题

    因为反射机制是通过对类的所有方法进行扫描,在一些对低端、对性能要求高的真机上,很容易因为性能消耗过高导致体验不佳。

    Eventbus3.0开始就使用编译时注解,通过EventBusAnnotationProcessor注解器在编译时就读取@Subscribe()注解并解析,即在Java编译成.class文件时就进行操作,处理@Subscribe所包含的信息,然后生成SubscriberInfoIndex索引类来保存所有订阅者关于订阅的信息,这样就比在运行时使用反射来获得这些订阅者的信息速度要快。

    在Eventbus的demo(EventBusPerformance)中,build->generated->source->apt中我们可以找到MyEventBusIndex索引类,我们对它进行分析一下:

    /** This class is generated by EventBus, do not edit. */
    public class MyEventBusIndex implements SubscriberInfoIndex {
        private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;
    
        static {
            SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();
    
            putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscriberClassEventBusAsync.class,
                    true, new SubscriberMethodInfo[] {
                new SubscriberMethodInfo("onEventAsync", TestEvent.class, ThreadMode.ASYNC),
            }));
    
            putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscribeClassEventBusMain.class,
                    true, new SubscriberMethodInfo[] {
                new SubscriberMethodInfo("onEventMainThread", TestEvent.class, ThreadMode.MAIN),
            }));
    
            putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscribeClassEventBusBackground.class,
                    true, new SubscriberMethodInfo[] {
                new SubscriberMethodInfo("onEventBackgroundThread", TestEvent.class, ThreadMode.BACKGROUND),
            }));
    
            putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscribeClassEventBusMainOrdered.class,
                    true, new SubscriberMethodInfo[] {
                new SubscriberMethodInfo("onEvent", TestEvent.class, ThreadMode.MAIN_ORDERED),
            }));
    
            putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.SubscribeClassEventBusDefault.class,
                    true, new SubscriberMethodInfo[] {
                new SubscriberMethodInfo("onEvent", TestEvent.class),
            }));
    
            putIndex(new SimpleSubscriberInfo(TestRunnerActivity.class, true, new SubscriberMethodInfo[] {
                new SubscriberMethodInfo("onEventMainThread", TestFinishedEvent.class, ThreadMode.MAIN),
            }));
    
        }
    
        private static void putIndex(SubscriberInfo info) {
            SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);
        }
    
        @Override
        public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {
            SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);
            if (info != null) {
                return info;
            } else {
                return null;
            }
        }
    }
    

    SUBSCRIBER_INDEX :订阅者对应订阅者信息的map集合
    SubscriberInfo:注解器生成的接口

    /** Base class for generated index classes created by annotation processing. */
    public interface SubscriberInfo {
        Class<?> getSubscriberClass();
        //获取订阅者类
        SubscriberMethod[] getSubscriberMethods();
        //获取订阅方法数组
        SubscriberInfo getSuperSubscriberInfo();
        //获取父类订阅信息
        boolean shouldCheckSuperclass();
        //是否检查父类
    }
    

    具体实现如下:

    /** Base class for generated subscriber meta info classes created by annotation processing. */
    public abstract class AbstractSubscriberInfo implements SubscriberInfo {
        private final Class subscriberClass;
        private final Class<? extends SubscriberInfo> superSubscriberInfoClass;
        private final boolean shouldCheckSuperclass;
    
        protected AbstractSubscriberInfo(Class subscriberClass, Class<? extends SubscriberInfo> superSubscriberInfoClass,
                                         boolean shouldCheckSuperclass) {
            this.subscriberClass = subscriberClass;
            this.superSubscriberInfoClass = superSubscriberInfoClass;
            this.shouldCheckSuperclass = shouldCheckSuperclass;
        }
    
        @Override
        public Class getSubscriberClass() {
            return subscriberClass;
        }
    
        @Override
        public SubscriberInfo getSuperSubscriberInfo() {
            if(superSubscriberInfoClass == null) {
                return null;
            }
            try {
                return superSubscriberInfoClass.newInstance();
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    
        @Override
        public boolean shouldCheckSuperclass() {
            return shouldCheckSuperclass;
        }
    
        protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType) {
            return createSubscriberMethod(methodName, eventType, ThreadMode.POSTING, 0, false);
        }
    
        protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType, ThreadMode threadMode) {
            return createSubscriberMethod(methodName, eventType, threadMode, 0, false);
        }
    
        protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType, ThreadMode threadMode,
                                                          int priority, boolean sticky) {
            try {
                //实际上仍是通过反射获取定义的相关参数,然后生成订阅方法SubscriberMethod,只不过这是在编译时就生成了
                Method method = subscriberClass.getDeclaredMethod(methodName, eventType);
                return new SubscriberMethod(method, eventType, threadMode, priority, sticky);
            } catch (NoSuchMethodException e) {
                throw new EventBusException("Could not find subscriber method in " + subscriberClass +
                        ". Maybe a missing ProGuard rule?", e);
            }
        }
    }
    
    public class SimpleSubscriberInfo extends AbstractSubscriberInfo {
    
        private final SubscriberMethodInfo[] methodInfos;
    
        public SimpleSubscriberInfo(Class subscriberClass, boolean shouldCheckSuperclass, SubscriberMethodInfo[] methodInfos) {
            super(subscriberClass, null, shouldCheckSuperclass);
            this.methodInfos = methodInfos;
        }
    
        @Override
        public synchronized SubscriberMethod[] getSubscriberMethods() {
            //根据抽象父类的反射方法生成订阅方法对象SubscriberMethod
            //返回所有的订阅方法
            int length = methodInfos.length;
            SubscriberMethod[] methods = new SubscriberMethod[length];
            for (int i = 0; i < length; i++) {
                SubscriberMethodInfo info = methodInfos[i];
                methods[i] = createSubscriberMethod(info.methodName, info.eventType, info.threadMode,
                        info.priority, info.sticky);
            }
            return methods;
        }
    }
    

    到这里,我们已经知道索引的具体含义,包括索引怎么生成订阅方法的底层逻辑,接下来我们继续回到通过索引获取订阅方法的上层函数:findUsingInfo(Class<?> subscriberClass)

    private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
            FindState findState = prepareFindState();
            findState.initForSubscriber(subscriberClass);
            while (findState.clazz != null) {
                //获取订阅者信息,下面会分析getSubscriberInfo(findState)
                findState.subscriberInfo = getSubscriberInfo(findState);
                if (findState.subscriberInfo != null) {
                    //生成订阅方法数组,具体逻辑前面已分析
                    SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
                    for (SubscriberMethod subscriberMethod : array) {
                        //校验订阅方法
                        if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
                            //把订阅方法添加到findState的subscriberMethods集合进行保存
                            findState.subscriberMethods.add(subscriberMethod);
                        }
                    }
                } else {
                    //根据索引获取不到订阅者信息,则通过反射获取
                    findUsingReflectionInSingleClass(findState);
                }
                findState.moveToSuperclass();
            }
            return getMethodsAndRelease(findState);
        }
    

    分析获取订阅者信息getSubscriberInfo(findState)

    private SubscriberInfo getSubscriberInfo(FindState findState) {
            if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
                 //获取父类的订阅信息并返回
                SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
                if (findState.clazz == superclassInfo.getSubscriberClass()) {
                    return superclassInfo;
                }
            }
            if (subscriberInfoIndexes != null) {
                //根据订阅类class,查找对应的索引类,找到后再通过索引类维护的Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX
               //返回对应的订阅信息
                for (SubscriberInfoIndex index : subscriberInfoIndexes) {
                    SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
                    if (info != null) {
                        return info;
                    }
                }
            }
            return null;
        }
    

    至此,我们已经分析完获取订阅方法的详细逻辑,包括使用反射获取索引获取。接下来继续分析找到全部订阅方法后,注册流程的下一步subscribe()方法的实现。

    3.2.2 subscribe(Object subscriber, SubscriberMethod subscriberMethod)

    // Must be called in synchronized block 必须在同步代码块里调用
        private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
            Class<?> eventType = subscriberMethod.eventType;
            Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
            //根据事件类型获取所有订阅该事件的Subscription集合,Subscription包括订阅者和订阅方法
            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;
                }
            }
    
            //将订阅者与对应的订阅事件存放到Map<Object, List<Class<?>>> typesBySubscriber;
            List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
            if (subscribedEvents == null) {
                subscribedEvents = new ArrayList<>();
                typesBySubscriber.put(subscriber, subscribedEvents);
            }
            subscribedEvents.add(eventType);
    
            //如果订阅方法支持sticky
            if (subscriberMethod.sticky) {
                // 支持事件继承,即响应事件类父类事件的方法
                if (eventInheritance) {
                    // Existing sticky events of all subclasses of eventType have to be considered.
                    // Note: Iterating over all events may be inefficient with lots of sticky events,
                    // thus data structure should be changed to allow a more efficient lookup
                    // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
                    Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
                    //遍历粘性sticky事件
                    for (Map.Entry<Class<?>, Object> entry : entries) {
                        Class<?> candidateEventType = entry.getKey();
                        // 判断eventType是否为candidateEventType,或者是candidateEventType的父类
                        if (eventType.isAssignableFrom(candidateEventType)) {
                            // 得到eventType的子类和eventType 对应的事件
                            Object stickyEvent = entry.getValue();
                            //// 立即发送粘性事件到订阅者newSubscription
                            checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                        }
                    }
                } else {
                    //不是事件继承的,则直接发送粘性事件
                    Object stickyEvent = stickyEvents.get(eventType);
                    checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                }
            }
        }
    

    到这里已经完成register()注册流程的全部解析,流程图(引用自EventBus 3.0 源码分析)如下

    register-flow-chart.png

    相关文章

      网友评论

          本文标题:Eventbus 3.1.1 源码解析(一)

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