如果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 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> eventTypes, Class>[] interfaces) {
/*对这个类直接实现的每个接口开始遍历*/
for (Class> interfaceClass : interfaces) {
/*如果这个接口还没有添加到列表接把他添加到列表*/
if (!eventTypes.contains(interfaceClass)) {
eventTypes.add(interfaceClass);
/*把这个接口所直接实现的所有接口的Class也添加进列表 递归调用*/
addInterfaces(eventTypes, interfaceClass.getInterfaces());
}
}
}