eventbus最早主要是通过注解方式实现的,最新的3.0版本主要是通过注解处理器来实现的,在代码的编译阶段产生模板类来提高运行效率,生成的模板代码一般在项目的generated目录下的source目录下apt目录可以看到模板代码,下面代码来自:(http://blog.csdn.net/u011240877/article/details/73196808)
public class MyEventBusIndex implements SubscriberInfoIndex { //实现了前面提到的接口
private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX; //保存类和订阅信息的缓存表
static {
SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();
//记录每个类中的订阅方法信息
putIndex(new SimpleSubscriberInfo(net.sxkeji.shixinandroiddemo2.activity.eventbus.EventBusRegisterActivity.class,
true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("readMessageFirst",
net.sxkeji.shixinandroiddemo2.activity.eventbus.MessageEvent.class, ThreadMode.POSTING, 5, false),
new SubscriberMethodInfo("readMessage", net.sxkeji.shixinandroiddemo2.activity.eventbus.MessageEvent.class,
ThreadMode.POSTING, 1, false),
}));
putIndex(new SimpleSubscriberInfo(net.sxkeji.shixinandroiddemo2.activity.eventbus.EventBusStickyActivity.class,
true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("readStickyMsg",
net.sxkeji.shixinandroiddemo2.activity.eventbus.MessageEvent.class, ThreadMode.MAIN, 0, true),
}));
}
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;
}
}
}
可以看到,里面根据注册eventbus的类生成了代码,里面主要有一个map,存储注册的Class对象以及其中所有的订阅方法,这样我们在post事件的时候可以很容易的根据Class对象获取该类中订阅的所有方法,然后根据事件类型来通知所注册的方法来进行响应。
发送事件的源代码
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
Class<?> eventClass = event.getClass();
boolean subscriptionFound = false;
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) { //如果没有订阅者,调用失败,根据配置,抛出一个 NoSubscriberEvent 事件
if (logNoSubscriberMessages) {
Log.d(TAG, "No subscribers registered for event " + eventClass);
}
if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
eventClass != SubscriberExceptionEvent.class) {
post(new NoSubscriberEvent(this, event));
}
}
}
根据发送的事件类型,找出所有订阅该事件的类以及接口,然后遍历每一个类,去回调订阅该事件的每一个方法。