EventBus源码解读详细注释(5)事件消息继承性分析 eventInheritance含义

[EventBus源码分析(一):入口函数提纲挈领(2.4版本)](http://blog.csdn.net/wangshihui512/article/details/51802172)
[EventBus源码分析(二):register方法保存事件的订阅者列表(2.4版本)](http://blog.csdn.net/wangshihui512/article/details/51819508)
[EventBus源码分析(三):post方法发布事件【获取事件的所有订阅者,反射调用订阅者事件处理方法】(2.4版本)](http://blog.csdn.net/wangshihui512/article/details/51821143)
[EventBus源码分析(四):线程模型分析(2.4版本)](http://blog.csdn.net/wangshihui512/article/details/51832001)
[EventBus源码解读详细注释(1)register的幕后黑手](http://blog.csdn.net/wangshihui512/article/details/50914817)
[EventBus源码解读详细注释(2)MainThread线程模型分析](http://blog.csdn.net/wangshihui512/article/details/50934012)
[EventBus源码解读详细注释(3)PostThread、MainThread、BackgroundThread、Async四种线程模式的区别](http://blog.csdn.net/wangshihui512/article/details/50935729)
[EventBus源码解读详细注释(4)register时刷新的两个map](http://blog.csdn.net/wangshihui512/article/details/50938663)
[EventBus源码解读详细注释(5)事件消息继承性分析 eventInheritance含义](http://blog.csdn.net/wangshihui512/article/details/50947102)
[EventBus源码解读详细注释(6)从事件发布到事件处理,究竟发生了什么!](http://blog.csdn.net/wangshihui512/article/details/50949960)



如果post(A),A extends B implements C,D implements C

那么onEvent(A)、onEvent(B)、onEvent(C)、onEvent(D)四个事件处理方法那些能得到调用呢

答案是onEvent(A)、onEvent(B)、onEvent(C)这三个

先用简单的实验验证,然后源码分析

写一个简单的Activity测试

public class MainActivity extends Activity {
    private static final String TAG="EventBus";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    protected void onStart() {
        super.onStart();
        Log.v(TAG, "onStart()");
        EventBus.getDefault().register(this);
        EventBus.getDefault().post(new A());
    }
    @Override
    protected void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
        Log.v(TAG, "onStop()");
    }
    public void onEvent(A msg){
        Log.v(TAG, "onEvent(A msg)");
    }
    public void onEvent(B msg){
        Log.v(TAG,"onEvent(B msg)");
    }
    public void onEvent(C msg){
        Log.v(TAG,"onEvent(C msg)");
    }
    public void onEvent(D msg){
        Log.v(TAG,"onEvent(D msg)");
    }
}
其中 A、B、C、D的继承关系如下:

public class A extends B implements C{}
public class B {}
public interface C {}
public class D implements  C{}
让程序跑起来,看一下log怎么说:

V/EventBus: onStart()
V/EventBus: onEvent(A msg)
V/EventBus: onEvent(C msg)
V/EventBus: onEvent(B msg)
V/EventBus: onStop()

由此可知EventBus中:

如果post(A),A extends B implements C,D implements C

那么onEvent(A)、onEvent(B)、onEvent(C)会被调用,onEvent(D)不会被调用

接下来看看源码怎么实现:

/*在此标志位为true的前提下
如果post(A),A extends B implements C,D implements C
那么onEvent(A)、onEvent(B)、onEvent(C)会被调用,onEvent(D)不会被调用*/
private final boolean eventInheritance;
这是一个成员属性标志位

发布事件的时候调用的是post,post内部调用下边这个方法

 private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
        /*获取事件的Class,所有事件的Class对应的订阅者列表在register的时候是已经保存了的*/
        Class eventClass = event.getClass();
        /*根据事件的Class找到订阅者的标志状态,初始化为false*/
        boolean subscriptionFound = false;
        /*
        * 比如 A extends B implements C  发布者post(A),那么找订阅者的时候不仅要找订阅了事件A的订阅者
        * 还要找订阅了B和C的订阅者*/
        if (eventInheritance) {
            /*找到事件的所有父类和所有实现的接口*/
            List> eventTypes = lookupAllEventTypes(eventClass);
            int countTypes = eventTypes.size();
            for (int h = 0; h < countTypes; h++) {
                Class clazz = eventTypes.get(h);
                subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
            }
            /*不考虑事件的继承性的话,那么处理起来就比较简单了*/
        } else {
            subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
        }

        if (!subscriptionFound) {
            if (logNoSubscriberMessages) {
                Log.d(TAG, "No subscribers registered for event " + eventClass);
            }
            if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
                    eventClass != SubscriberExceptionEvent.class) {
                post(new NoSubscriberEvent(this, event));
            }
        }
    }

前边说过了EventBus维护了两个重要的map。其中一个就是事件的Class到能处理此事件的所有订阅者列表的map,因此不仅要把事件的Class存入map中的订阅者列表,还要把事件的所有父类和所有实现的接口的Class存入订阅者列表。下边是找到某个类所有父类和所有实现接口的方法:

/** Looks up all Class objects including super classes and interfaces. Should also work for interfaces. */
    /*找到事件的所有父类和实现的接口,以Class列表的形式返回*/
    private List> lookupAllEventTypes(Class eventClass) {
        /*private static final Map, List>> eventTypesCache = new HashMap, List>>();*/
        synchronized (eventTypesCache) {
            /*查看缓存,看能否命中*/
            List> eventTypes = eventTypesCache.get(eventClass);
            /*缓存不命中*/
            if (eventTypes == null) {
                /*创建事件类型列表*/
                eventTypes = new ArrayList>();
                Class clazz = eventClass;
                /*getSuperclass()返回null的情况:Class表示的类为Object、基本数据类型、接口或者void*/
                while (clazz != null) {
                    eventTypes.add(clazz);
                    /*把接口对应的Class也添加进Class列表
                    * clazz.getInterfaces():返回clazz表示的类直接实现的接口的Class列表,不包括间接实现的接口
                    * */
                    addInterfaces(eventTypes, clazz.getInterfaces());
                    /** public Class getSuperclass() :
                     * Returns the Class object which represents the superclass of the
                     * class represented by this  Class. If this  Class represents
                     * the Object class, a primitive type, an interface or void then the
                     * method returns null. If this Class represents an array
                     * class then the  Object class is returned.
                     */

                    clazz = clazz.getSuperclass();
                }
                /*找到一个事件的所有父类和所有实现接口的Class挺复杂的,循环加递归的,还是加入缓存机制提高性能吧*/
                eventTypesCache.put(eventClass, eventTypes);
            }
            return eventTypes;
        }
    }

    /** Recurses through super interfaces. 获取某个类直接实现的所有接口,包括间接实现的
     * @param eventTypes
     * @param interfaces*/
    static void addInterfaces(List> eventTypes, Class[] interfaces) {
        /*对这个类直接实现的每个接口开始遍历*/
        for (Class interfaceClass : interfaces) {
            /*如果这个接口还没有添加到列表接把他添加到列表*/
            if (!eventTypes.contains(interfaceClass)) {
                eventTypes.add(interfaceClass);
                /*把这个接口所直接实现的所有接口的Class也添加进列表 递归调用*/
                addInterfaces(eventTypes, interfaceClass.getInterfaces());
            }
        }
    }



你可能感兴趣的:(Android源码分析)