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

来源:互联网 发布:python 矩阵转图片 编辑:程序博客网 时间:2024/06/05 16:09

[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<Class<?>> 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<Class<?>> lookupAllEventTypes(Class<?> eventClass) {        /*private static final Map<Class<?>, List<Class<?>>> eventTypesCache = new HashMap<Class<?>, List<Class<?>>>();*/        synchronized (eventTypesCache) {            /*查看缓存,看能否命中*/            List<Class<?>> eventTypes = eventTypesCache.get(eventClass);            /*缓存不命中*/            if (eventTypes == null) {                /*创建事件类型列表*/                eventTypes = new ArrayList<Class<?>>();                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<? super T> 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<Class<?>> eventTypes, Class<?>[] interfaces) {        /*对这个类直接实现的每个接口开始遍历*/        for (Class<?> interfaceClass : interfaces) {            /*如果这个接口还没有添加到列表接把他添加到列表*/            if (!eventTypes.contains(interfaceClass)) {                eventTypes.add(interfaceClass);                /*把这个接口所直接实现的所有接口的Class也添加进列表 递归调用*/                addInterfaces(eventTypes, interfaceClass.getInterfaces());            }        }    }


                                             
0 0
原创粉丝点击