目录
dispatchProducerResultToHandler
otto简单使用说明
单例创建Bus类
register用于注册,unregister用于取消注册
post用于发送事件
@Subscribe注解修饰的方法用于接收事件
@Produce注解修饰的方法用于创建并发送事件
Bus的构造方法
先看Bus类的成员变量,如下代码,根据给的注释大致能猜测这些成员变量的含义,具体的作用还是等到下面具体代码执行的流程再来看看。
private final ConcurrentMap<Class<?>, Set<EventHandler>> handlersByType =
new ConcurrentHashMap<Class<?>, Set<EventHandler>>();
private final ConcurrentMap<Class<?>, EventProducer> producersByType =
new ConcurrentHashMap<Class<?>, EventProducer>();
private final String identifier;
private final ThreadEnforcer enforcer;
private final HandlerFinder handlerFinder;
private final ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>> eventsToDispatch =
new ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>>() {
@Override protected ConcurrentLinkedQueue<EventWithHandler> initialValue() {
return new ConcurrentLinkedQueue<EventWithHandler>();
}
};
private final ThreadLocal<Boolean> isDispatching = new ThreadLocal<Boolean>() {
@Override protected Boolean initialValue() {
return false;
}
};
public Bus() {
this(DEFAULT_IDENTIFIER);
}
public Bus(String identifier) {
this(ThreadEnforcer.MAIN, identifier);
}
public Bus(ThreadEnforcer enforcer) {
this(enforcer, DEFAULT_IDENTIFIER);
}
public Bus(ThreadEnforcer enforcer, String identifier) {
this(enforcer, identifier, HandlerFinder.ANNOTATED);
}
Bus(ThreadEnforcer enforcer, String identifier, HandlerFinder handlerFinder) {
this.enforcer = enforcer;
this.identifier = identifier;
this.handlerFinder = handlerFinder;
}
可以看到,使用代码配置好的参数,enforcer为ThreadEnforcer.MAIN,handlerFinder为HandlerFinder.ANNOTATED。
先看ThreadEnforcer.MAIN,这应该是判断是否在主线程执行的判断,如果不是,就报出异常。
ThreadEnforcer MAIN = new ThreadEnforcer() {
@Override public void enforce(Bus bus) {
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("Event bus " + bus + " accessed from non-main thread " + Looper.myLooper());
}
}
};
再看HandlerFinder.ANNOTATED,从HandlerFinder这个单词字面意思理解,就是一个用来查找某样事务的工具类。从下面的代码也可以看到,ANNOTATED的findAllProducers和findAllSubscribers方法都交给了AnnotatedHandlerFinder类去处理。
HandlerFinder ANNOTATED = new HandlerFinder() {
@Override
public Map<Class<?>, EventProducer> findAllProducers(Object listener) {
return AnnotatedHandlerFinder.findAllProducers(listener);
}
@Override
public Map<Class<?>, Set<EventHandler>> findAllSubscribers(Object listener) {
return AnnotatedHandlerFinder.findAllSubscribers(listener);
}
};
到此为止,Bus类已经创建好了。
Bus的register方法
public void register(Object object) {
if (object == null) {
throw new NullPointerException("Object to register must not be null.");
}
enforcer.enforce(this);
// findAllProducers从类中找到所有发送消息的方法
Map<Class<?>, EventProducer> foundProducers = handlerFinder.findAllProducers(object);
for (Class<?> type : foundProducers.keySet()) {
// 此处注意,在使用Produce注解时,在应用里一个返回事件只能出现一次,否则就会报错
final EventProducer producer = foundProducers.get(type);
// 据此可知,producersByType是一个key为事件class对象,value为EventProducer的并发集合
EventProducer previousProducer = producersByType.putIfAbsent(type, producer);
//checking if the previous producer existed
if (previousProducer != null) {
throw new IllegalArgumentException("Producer method for type " + type
+ " found on type " + producer.target.getClass()
+ ", but already registered by type " + previousProducer.target.getClass() + ".");
}
// 对于类里面包含了Produce注解的方法,一旦执行register方法,就会发送事件给订阅事件的实例对象
// 根据事件class对象,找到订阅此对象的Set集合
Set<EventHandler> handlers = handlersByType.get(type);
if (handlers != null && !handlers.isEmpty()) {
for (EventHandler handler : handlers) {
// 分发事件给每个EventHandler
dispatchProducerResultToHandler(handler, producer);
}
}
}
// findAllSubscribers找到所有的订阅者
// handlersByType是一个key为事件class对象,value为EventHandler集合的并发集合
Map<Class<?>, Set<EventHandler>> foundHandlersMap = handlerFinder.findAllSubscribers(object);
for (Class<?> type : foundHandlersMap.keySet()) {
Set<EventHandler> handlers = handlersByType.get(type);
if (handlers == null) {
//concurrent put if absent
Set<EventHandler> handlersCreation = new CopyOnWriteArraySet<EventHandler>();
handlers = handlersByType.putIfAbsent(type, handlersCreation);
if (handlers == null) {
handlers = handlersCreation;
}
}
final Set<EventHandler> foundHandlers = foundHandlersMap.get(type);
// 添加进handlersByType
if (!handlers.addAll(foundHandlers)) {
throw new IllegalArgumentException("Object already registered.");
}
}
// 遍历foundHandlersMap
for (Map.Entry<Class<?>, Set<EventHandler>> entry : foundHandlersMap.entrySet()) {
Class<?> type = entry.getKey();
EventProducer producer = producersByType.get(type);
if (producer != null && producer.isValid()) {
Set<EventHandler> foundHandlers = entry.getValue();
for (EventHandler foundHandler : foundHandlers) {
if (!producer.isValid()) {
break;
}
if (foundHandler.isValid()) {
// 分发EventProducer的事件给EventHandler,因为它们发送和接收的事件类型相同
dispatchProducerResultToHandler(foundHandler, producer);
}
}
}
}
}
上面的步骤可以理解为三步:
1.findAllProducers -> dispatchProducerResultToHandler,一旦有
2.findAllSubscribers
3.更新订阅对象信息 -> dispatchProducerResultToHandler
其中,handlersByType和producersByType含义如下:
// handlersByType是一个key为事件class对象,value为EventHandler集合的并发集合
private final ConcurrentMap<Class<?>, Set<EventHandler>> handlersByType =
new ConcurrentHashMap<Class<?>, Set<EventHandler>>();
// producersByType是一个key为事件class对象,value为EventProducer的并发集合
private final ConcurrentMap<Class<?>, EventProducer> producersByType =
new ConcurrentHashMap<Class<?>, EventProducer>();
findAllProducers
findAllProducers是AnnotatedHandlerFinder的静态方法
static Map<Class<?>, EventProducer> findAllProducers(Object listener) {
final Class<?> listenerClass = listener.getClass();
Map<Class<?>, EventProducer> handlersInMethod = new HashMap<Class<?>, EventProducer>();
Map<Class<?>, Method> methods = PRODUCERS_CACHE.get(listenerClass);
if (null == methods) {
methods = new HashMap<Class<?>, Method>();
// 找到包含Produce注解的方法
loadAnnotatedProducerMethods(listenerClass, methods);
}
if (!methods.isEmpty()) {
for (Map.Entry<Class<?>, Method> e : methods.entrySet()) {
// 封装一个EventProducer,包含实例对象以及对应的Method方法对象,更新到handlersInMethod中,handlersInMethod的key为Produce注解方法的返回事件class对象
EventProducer producer = new EventProducer(listener, e.getValue());
handlersInMethod.put(e.getKey(), producer);
}
}
return handlersInMethod;
}
private static void loadAnnotatedProducerMethods(Class<?> listenerClass,
Map<Class<?>, Method> producerMethods) {
Map<Class<?>, Set<Method>> subscriberMethods = new HashMap<Class<?>, Set<Method>>();
// 最终调用loadAnnotatedMethods方法
loadAnnotatedMethods(listenerClass, producerMethods, subscriberMethods);
}
private static void loadAnnotatedSubscriberMethods(Class<?> listenerClass,
Map<Class<?>, Set<Method>> subscriberMethods) {
Map<Class<?>, Method> producerMethods = new HashMap<Class<?>, Method>();
// 最终调用loadAnnotatedMethods方法
loadAnnotatedMethods(listenerClass, producerMethods, subscriberMethods);
}
private static void loadAnnotatedMethods(Class<?> listenerClass,
Map<Class<?>, Method> producerMethods, Map<Class<?>, Set<Method>> subscriberMethods) {
// 遍历Method
for (Method method : listenerClass.getDeclaredMethods()) {
// The compiler sometimes creates synthetic bridge methods as part of the
// type erasure process. As of JDK8 these methods now include the same
// annotations as the original declarations. They should be ignored for
// subscribe/produce.
if (method.isBridge()) {
continue;
}
// Method包含注解Subscribe
if (method.isAnnotationPresent(Subscribe.class)) {
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length != 1) {
throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation but requires "
+ parameterTypes.length + " arguments. Methods must require a single argument.");
}
Class<?> eventType = parameterTypes[0];
if (eventType.isInterface()) {
throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation on " + eventType
+ " which is an interface. Subscription must be on a concrete class type.");
}
if ((method.getModifiers() & Modifier.PUBLIC) == 0) {
throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation on " + eventType
+ " but is not 'public'.");
}
// 保存找到的方法,subscriberMethods是key为事件class对象,value为Method集合的映射
Set<Method> methods = subscriberMethods.get(eventType);
if (methods == null) {
methods = new HashSet<Method>();
subscriberMethods.put(eventType, methods);
}
methods.add(method);
} else if (method.isAnnotationPresent(Produce.class)) { // Method包含注解Produce
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length != 0) {
throw new IllegalArgumentException("Method " + method + "has @Produce annotation but requires "
+ parameterTypes.length + " arguments. Methods must require zero arguments.");
}
if (method.getReturnType() == Void.class) {
throw new IllegalArgumentException("Method " + method
+ " has a return type of void. Must declare a non-void type.");
}
Class<?> eventType = method.getReturnType();
if (eventType.isInterface()) {
throw new IllegalArgumentException("Method " + method + " has @Produce annotation on " + eventType
+ " which is an interface. Producers must return a concrete class type.");
}
if (eventType.equals(Void.TYPE)) {
throw new IllegalArgumentException("Method " + method + " has @Produce annotation but has no return type.");
}
if ((method.getModifiers() & Modifier.PUBLIC) == 0) {
throw new IllegalArgumentException("Method " + method + " has @Produce annotation on " + eventType
+ " but is not 'public'.");
}
if (producerMethods.containsKey(eventType)) {
throw new IllegalArgumentException("Producer for type " + eventType + " has already been registered.");
}
// 保存方法
producerMethods.put(eventType, method);
}
}
// 保存到当前key为订阅类的class对象的并发集合映射上
PRODUCERS_CACHE.put(listenerClass, producerMethods);
SUBSCRIBERS_CACHE.put(listenerClass, subscriberMethods);
}
上述过程主要完成以下工作:
1.找到注解Subscribe和Produce的方法, 更新PRODUCERS_CACHE和SUBSCRIBERS_CACHE
2.返回一个key为事件class对象,value为EventProducer的映射,EventProducer中包含了实例对象和包含注解Produce方法的信息
其中,PRODUCERS_CACHE和SUBSCRIBERS_CACHE含义如下:
/** Cache event bus producer methods for each class. */
// 缓存用并发集合,key为类的class对象,value为Map,跟具体的注册实例对象无关,跟类有关
private static final ConcurrentMap<Class<?>, Map<Class<?>, Method>> PRODUCERS_CACHE =
new ConcurrentHashMap<Class<?>, Map<Class<?>, Method>>();
/** Cache event bus subscriber methods for each class. */
// 缓存用并发集合,key为类的class对象,value为Map,跟具体的注册实例对象无关,跟类有关
private static final ConcurrentMap<Class<?>, Map<Class<?>, Set<Method>>> SUBSCRIBERS_CACHE =
new ConcurrentHashMap<Class<?>, Map<Class<?>, Set<Method>>>();
dispatchProducerResultToHandler
Producer产生的事件传给订阅者
private void dispatchProducerResultToHandler(EventHandler handler, EventProducer producer) {
Object event = null;
try {
// 反射获取需要发送的事件
event = producer.produceEvent();
} catch (InvocationTargetException e) {
throwRuntimeException("Producer " + producer + " threw an exception.", e);
}
if (event == null) {
return;
}
dispatch(event, handler);
}
protected void dispatch(Object event, EventHandler wrapper) {
try {
wrapper.handleEvent(event);
} catch (InvocationTargetException e) {
throwRuntimeException(
"Could not dispatch event: " + event.getClass() + " to handler " + wrapper, e);
}
}
EventHandler的handleEvent方法
public void handleEvent(Object event) throws InvocationTargetException {
if (!valid) {
throw new IllegalStateException(toString() + " has been invalidated and can no longer handle events.");
}
try {
method.invoke(target, event);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
} catch (InvocationTargetException e) {
if (e.getCause() instanceof Error) {
throw (Error) e.getCause();
}
throw e;
}
}
findAllSubscribers
findAllSubscribers是AnnotatedHandlerFinder的静态方法,该方法返回的是key为订阅事件class对象,value为EventHandler的集合,其中EventHandler是订阅者实例对象及其方法Method的包装类。
static Map<Class<?>, Set<EventHandler>> findAllSubscribers(Object listener) {
Class<?> listenerClass = listener.getClass();
Map<Class<?>, Set<EventHandler>> handlersInMethod = new HashMap<Class<?>, Set<EventHandler>>();
Map<Class<?>, Set<Method>> methods = SUBSCRIBERS_CACHE.get(listenerClass);
if (null == methods) {
methods = new HashMap<Class<?>, Set<Method>>();
loadAnnotatedSubscriberMethods(listenerClass, methods);
}
if (!methods.isEmpty()) {
for (Map.Entry<Class<?>, Set<Method>> e : methods.entrySet()) {
Set<EventHandler> handlers = new HashSet<EventHandler>();
for (Method m : e.getValue()) {
// 封装订阅实例和Method对象为EventHandler
handlers.add(new EventHandler(listener, m));
}
// handlersInMethod是key为订阅事件class对象,value为EventHandler的集合,由此,一个类里面可以订阅多个相同事件,这个好像没啥必要
handlersInMethod.put(e.getKey(), handlers);
}
}
return handlersInMethod;
}
Bus的post方法
public void post(Object event) {
if (event == null) {
throw new NullPointerException("Event to post must not be null.");
}
enforcer.enforce(this);
// 找到event的class及其父类的class
Set<Class<?>> dispatchTypes = flattenHierarchy(event.getClass());
boolean dispatched = false;
// 遍历class
for (Class<?> eventType : dispatchTypes) {
// 根据事件class对象,找到对应的订阅者包装类集合
Set<EventHandler> wrappers = getHandlersForEventType(eventType);
if (wrappers != null && !wrappers.isEmpty()) {
dispatched = true;
for (EventHandler wrapper : wrappers) {
// 加入到队列中
enqueueEvent(event, wrapper);
}
}
}
if (!dispatched && !(event instanceof DeadEvent)) {
post(new DeadEvent(this, event));
}
// 执行队列中的事件任务
dispatchQueuedEvents();
}
post方法用于发送事件,具体执行流程大致如下:
1.根据事件Class对象,找到对应的EventHandler订阅者对象
2.将事件对象和EventHandler对象包装成EventWithHandler对象,加入到队列中
3.启动执行这个队列中的任务
其他详细代码如下:
flattenHierarchy方法
Set<Class<?>> flattenHierarchy(Class<?> concreteClass) {
Set<Class<?>> classes = flattenHierarchyCache.get(concreteClass);
if (classes == null) {
Set<Class<?>> classesCreation = getClassesFor(concreteClass);
classes = flattenHierarchyCache.putIfAbsent(concreteClass, classesCreation);
if (classes == null) {
classes = classesCreation;
}
}
return classes;
}
private final ConcurrentMap<Class<?>, Set<Class<?>>> flattenHierarchyCache =
new ConcurrentHashMap<Class<?>, Set<Class<?>>>();
private Set<Class<?>> getClassesFor(Class<?> concreteClass) {
List<Class<?>> parents = new LinkedList<Class<?>>();
Set<Class<?>> classes = new HashSet<Class<?>>();
parents.add(concreteClass);
while (!parents.isEmpty()) {
Class<?> clazz = parents.remove(0);
classes.add(clazz);
Class<?> parent = clazz.getSuperclass();
if (parent != null) {
parents.add(parent);
}
}
return classes;
}
getHandlersForEventType方法
Set<EventHandler> getHandlersForEventType(Class<?> type) {
return handlersByType.get(type);
}
enqueueEvent方法
protected void enqueueEvent(Object event, EventHandler handler) {
eventsToDispatch.get().offer(new EventWithHandler(event, handler));
}
private final ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>> eventsToDispatch =
new ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>>() {
@Override protected ConcurrentLinkedQueue<EventWithHandler> initialValue() {
return new ConcurrentLinkedQueue<EventWithHandler>();
}
};
dispatchQueuedEvents方法
protected void dispatchQueuedEvents() {
// don't dispatch if we're already dispatching, that would allow reentrancy and out-of-order events. Instead, leave
// the events to be dispatched after the in-progress dispatch is complete.
if (isDispatching.get()) {
return;
}
isDispatching.set(true);
try {
while (true) {
EventWithHandler eventWithHandler = eventsToDispatch.get().poll();
if (eventWithHandler == null) {
break;
}
if (eventWithHandler.handler.isValid()) {
dispatch(eventWithHandler.event, eventWithHandler.handler);
}
}
} finally {
isDispatching.set(false);
}
}
Bus的unregister方法
注销跟该对象相关的信息,防止内存泄漏。
public void unregister(Object object) {
if (object == null) {
throw new NullPointerException("Object to unregister must not be null.");
}
enforcer.enforce(this);
// 找到跟该对象相关的所有EventProducer
Map<Class<?>, EventProducer> producersInListener = handlerFinder.findAllProducers(object);
// 遍历EventProducer集合,从producersByType中删除并将删除的EventProducer置为无效
for (Map.Entry<Class<?>, EventProducer> entry : producersInListener.entrySet()) {
final Class<?> key = entry.getKey();
EventProducer producer = getProducerForEventType(key);
EventProducer value = entry.getValue();
if (value == null || !value.equals(producer)) {
throw new IllegalArgumentException(
"Missing event producer for an annotated method. Is " + object.getClass()
+ " registered?");
}
producersByType.remove(key).invalidate();
}
// 找到跟该对象相关的所有EventHandler
Map<Class<?>, Set<EventHandler>> handlersInListener = handlerFinder.findAllSubscribers(object);
// 遍历EventHandler集合,从handlersByType中删除并将删除的EventHandler置为无效
for (Map.Entry<Class<?>, Set<EventHandler>> entry : handlersInListener.entrySet()) {
Set<EventHandler> currentHandlers = getHandlersForEventType(entry.getKey());
Collection<EventHandler> eventMethodsInListener = entry.getValue();
if (currentHandlers == null || !currentHandlers.containsAll(eventMethodsInListener)) {
throw new IllegalArgumentException(
"Missing event handler for an annotated method. Is " + object.getClass()
+ " registered?");
}
for (EventHandler handler : currentHandlers) {
if (eventMethodsInListener.contains(handler)) {
handler.invalidate();
}
}
currentHandlers.removeAll(eventMethodsInListener);
}
}