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
- EventBus源码解读详细注释(5)事件消息继承性分析 eventInheritance含义
- EventBus源码解读详细注释(2)MainThread线程模型分析
- EventBus源码解读详细注释(6)从事件发布到事件处理,究竟发生了什么!
- EventBus源码解读详细注释(1)register的幕后黑手
- EventBus源码解读详细注释(4)register时刷新的两个map
- EventBus源码注释分析
- EventBus源码解读详细注释(3)PostThread、MainThread、BackgroundThread、Async四种线程模式的区别
- 解读EventBus源码
- EventBus (二) 源码分析
- 【源码解读】Handler消息机制流程分析
- EventBus事件分发框架解读
- Google-Guava-EventBus源码解读
- Google-Guava-EventBus源码解读
- EventBus源码分析(二):register方法保存事件的订阅者列表(2.4版本)
- EventBus源码分析(一):EventBus的使用
- EventBus分析--事件分发
- EventBus(二)之源码分析
- EventBus 2.4 源码分析
- ViewPager左右滑动页面,下面的按钮跟着动态变化
- java0x01 eclipse基本操作
- linux下svn配置
- Python中的陷阱
- Java hashCode
- EventBus源码解读详细注释(5)事件消息继承性分析 eventInheritance含义
- 获取指定时间的offsets类:GetOffsetShell 源码导读
- 跟着Google学Android —— 1.3 来创建个非常简单的UI吧
- 1.1. Creating a New Project from Maven Archetype 从Maven Archetype创建一个新项目
- OC中关于时间的几个函数及格式化时间
- AlertController工具类的封装,让AlertController变得更简单
- 数组去重
- 车牌识别中的车牌定位
- git的初级使用