EventBus官网
订阅的事件类
public static class MessageEvent { /* Additional fields if needed */ }
订阅方法,需要@Subscribe注解声明,可以设置处理该事件的线程等
@Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MessageEvent event) {/* Do something */};
订阅者的注册和反注册,如在Activity和Fragment的中添加
@Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { super.onStop(); EventBus.getDefault().unregister(this); }
post发送事件后,上述步骤2.中的订阅方法可以接受事件并回调处理
EventBus.getDefault().post(new MessageEvent());
通过单例和建造者创建EventBus实例;
通过@Subscribe添加订阅方法,可以设置订阅方法的优先级,所属处理线程,是否是粘性;
register注册方法中,通过两种方式获取订阅者中的所有订阅方法:①通过运行时反射,收集被@Subscribe注解声明的方法;②通过编译时索引,即apt(AbstractProcessor的process(Set<? extends TypeElement> annotations, RoundEnvironment env))方法,将被@Subscribe注解声明的方法,编写至build下的java文件;
subscribe订阅方法,将当前订阅者内的所有订阅方法放入subscribedEvents集合;
post推送event事件后,根据存储的订阅信息集合查找匹配的对象,进行invoke反射调用订阅了event事件的订阅方法;
@Subscribe
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Subscribe { /*订阅者在哪种线程中做处理*/ //ThreadMode包含 //1.POSTING-事件发布者和订阅者处于同一线程,没有线程切换,开销最小 //2.MAIN-订阅方法于主线程中处理 //3.MAIN_ORDERED-订阅者于主线程中处理,并按优先级队列有序处理 //4.BACKGROUND-订阅者于子线程中处理,并按优先级队列有序处理 //5.ASYNC-订阅者于线程池中处理,适合网络访问 ThreadMode threadMode() default ThreadMode.POSTING; /*是否是粘性事件*/ boolean sticky() default false; /*同一线程中,优先级高的订阅者先收到事件*/ int priority() default 0; }
EventBus.getDefault()
使用设计模式:单例和建造者
class EventBus { //... public static EventBus getDefault() { EventBus instance = defaultInstance; if (instance == null) { synchronized (EventBus.class) { instance = EventBus.defaultInstance; if (instance == null) { instance = EventBus.defaultInstance = new EventBus(); } } } return instance; } //... EventBus(EventBusBuilder builder) { logger = builder.getLogger(); subscriptionsByEventType = new HashMap<>(); typesBySubscriber = new HashMap<>(); stickyEvents = new ConcurrentHashMap<>(); mainThreadSupport = builder.getMainThreadSupport(); mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null; backgroundPoster = new BackgroundPoster(this); asyncPoster = new AsyncPoster(this); indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0; subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes, builder.strictMethodVerification, builder.ignoreGeneratedIndex); logSubscriberExceptions = builder.logSubscriberExceptions; logNoSubscriberMessages = builder.logNoSubscriberMessages; sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent; sendNoSubscriberEvent = builder.sendNoSubscriberEvent; throwSubscriberException = builder.throwSubscriberException; eventInheritance = builder.eventInheritance; executorService = builder.executorService; } //... }
.register(this)
//{msg1: [{firstActivity, onMsg1(msg1)}]} //{msg2: [{firstActivity, onMsg2(msg2)}, {secondActivity, onMsg2(msg2)}]} //{msg3: [{secondActivity, onMsg3(msg3)}]} private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType; //{firstActivity: [Msg1, Msg2]} //{secondActivity: [Msg2, Msg3]} private final Map<Object, List<Class<?>>> typesBySubscriber; final List<SubscriberMethod> subscriberMethods = new ArrayList<>(); //{msg1: onMsg1(msg1)} //{msg2: onMsg2(msg2)} //{msg3: onMsg3(msg3)} final Map<Class, Object> anyMethodByEventType = new HashMap<>(); //{onMsg1()>0001, firstActivity} //{onMsg2()>0002, firstActivity} //{onMsg2()>0002, secondActivity} //{onMsg3()>0003, secondActivity} final Map<String, Class> subscriberClassByMethodKey = new HashMap<>();
/** 订阅者需注册才能接收事件,且不再使用时须解注册;订阅方法必须被@Subscribe注解声明,可以配置其线程和优先级 */ public void register(Object subscriber) { //subscriber是订阅者[如firstActivity或secondActivity] Class<?> subscriberClass = subscriber.getClass(); //找出当前subscriber内的所有订阅方法 List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass); synchronized (this) { //遍历当前subscriber内的订阅方法 for (SubscriberMethod subscriberMethod : subscriberMethods) { //开始订阅 subscribe(subscriber, subscriberMethod); } } }
findSubscriberMethods(subscriberClass)
//如找出firstActivity中的onMsg1/onMsg2订阅方法 List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) { //缓存中取订阅方法[METHOD_CACHE:ConcurrentHashMap<Class<?>, List<SubscriberMethod>>] List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass); if (subscriberMethods != null) { return subscriberMethods; } //true=>运行时反射获取订阅方法 //false=>编译时生成订阅方法索引 if (ignoreGeneratedIndex) { subscriberMethods = findUsingReflection(subscriberClass); } else { subscriberMethods = findUsingInfo(subscriberClass); } //若当前activity或fragment中未定义订阅方法则异常提示 if (subscriberMethods.isEmpty()) { throw new EventBusException("Subscriber " + subscriberClass + " and its super classes have no public methods with the @Subscribe annotation"); //将当前订阅者内的所有订阅方法置于缓存中 } else { METHOD_CACHE.put(subscriberClass, subscriberMethods); return subscriberMethods; } }
private List<SubscriberMethod> findUsingReflection(Class<?> subscriberClass) { FindState findState = prepareFindState(); findState.initForSubscriber(subscriberClass); while (findState.clazz != null) { //通过反射找出订阅者内所有的订阅方法 findUsingReflectionInSingleClass(findState); findState.moveToSuperclass(); } return getMethodsAndRelease(findState); }
private void findUsingReflectionInSingleClass(FindState findState) { Method[] methods; try { // This is faster than getMethods, especially when subscribers are fat classes like Activities //获取订阅者类中所有方法 methods = findState.clazz.getDeclaredMethods(); } catch (Throwable th) { // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149 try { //获取订阅者类及其父类中所有方法 methods = findState.clazz.getMethods(); } catch (LinkageError error) { // super class of NoClassDefFoundError to be a bit more broad... String msg = "Could not inspect methods of " + findState.clazz.getName(); if (ignoreGeneratedIndex) { msg += ". Please consider using EventBus annotation processor to avoid reflection."; } else { msg += ". Please make this class visible to EventBus annotation processor to avoid reflection."; } throw new EventBusException(msg, error); } //getMethods()方法中已获取父类方法=>所以此处设置跳过父类检查 findState.skipSuperClasses = true; } //遍历所有方法 for (Method method : methods) { //滤出public修饰的方法[public xxMethod(...) {}] int modifiers = method.getModifiers(); if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) { Class<?>[] parameterTypes = method.getParameterTypes(); //滤出只有一个参数的方法[public xxMethod(Object obj) {}] if (parameterTypes.length == 1) { //滤出被@Subscribe注解声明的方法[@Subscribe public xxMethod(Object obj) {}] Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class); if (subscribeAnnotation != null) { //eventType为方法[@Subscribe public xxMethod(Object obj) {}]中的参数类型Object //如方法[@Subscribe public void onMessageEvent(MessageEvent event) {}]中的MessageEvent Class<?> eventType = parameterTypes[0]; //订阅者与订阅方法集合是否已添加当前method和eventType对 if (findState.checkAdd(method, eventType)) { //checkAdd返回true即该method和eventType键值对不在subscriberMethods[订阅者与订阅方法集合]中 //=>根据@Subscribe注解属性并创建SubscriberMethod实例添加至subscriberMethods中 ThreadMode threadMode = subscribeAnnotation.threadMode(); findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode, subscribeAnnotation.priority(), subscribeAnnotation.sticky())); } } //提示被@Subscribe注解声明的方法必须有且只能有一个参数 } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) { String methodName = method.getDeclaringClass().getName() + "." + method.getName(); throw new EventBusException("@Subscribe method " + methodName + "must have exactly 1 parameter but has " + parameterTypes.length); } //提示被@Subscribe注解声明的方法必须是被public修饰的,且不能被static和abstract修饰 } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) { String methodName = method.getDeclaringClass().getName() + "." + method.getName(); throw new EventBusException(methodName + " is a illegal @Subscribe method: must be public, non-static, and non-abstract"); } } }
boolean checkAdd(Method method, Class<?> eventType) { // 2 level check: 1st level with event type only (fast), 2nd level with complete signature when required. // Usually a subscriber doesn't have methods listening to the same event type. /* 关于Object obj = map.put(key);=>若key对应值不存在,则返回null;若key对应值存在,则回原先存储的value值,示例如下 Map<String, String> map = new HashMap<>(); String put1 = map.put("name", "Ashe"); System.out.println("put1:" + put1);//put1:null String put2 = map.put("name", "Annie"); System.out.println("put2:" + put2);//put2:Ashe */ //如订阅者有如下三个订阅方法 //@Subscribe(...) public void listen1(NewsMessage msg) {} //@Subscribe(...) public void listen2(NewsMessage msg) {} //@Subscribe(...) public void listen3(WeatherMessage msg) {} //第一次:put(newsMessage, listen1) => existing == null => return true => 调用上述findState.subscriberMethods.add方法 //第二次:put(newsMessage, listen2) => existing == listen1 => else {...} //第三次:put(weatherMessage, listen3) => existing == null => return true => 调用上述findState.subscriberMethods.add方法 Object existing = anyMethodByEventType.put(eventType, method); if (existing == null) { return true; } else { if (existing instanceof Method) { if (!checkAddWithMethodSignature((Method) existing, eventType)) { // Paranoia check throw new IllegalStateException(); } // Put any non-Method object to "consume" the existing Method anyMethodByEventType.put(eventType, this); } return checkAddWithMethodSignature(method, eventType); } }
private boolean checkAddWithMethodSignature(Method method, Class<?> eventType) { methodKeyBuilder.setLength(0); methodKeyBuilder.append(method.getName()); methodKeyBuilder.append('>').append(eventType.getName()); //订阅方法的标识 String methodKey = methodKeyBuilder.toString(); //订阅方法所在的订阅者类 Class<?> methodClass = method.getDeclaringClass(); //将方法标识和订阅者类添加至subscriberClassByMethodKey集合 Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass); /* isAssignableFrom(clz)从类继承角度判断是否为clz的父类 instanceof clz从实例继承角度判断是否为clz的子类 */ //subscriberClassByMethodKey中第一次添加订阅方法和订阅者类||订阅方法及其父类已被添加至subscriberClassByMethodKey中 //即subscriberClassByMethodKey之前并未添加该订阅方法和该子类信息对 if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) { // Only add if not already found in a sub class //调用上述findState.subscriberMethods.add方法 return true; } else { // Revert the put, old class is further down the class hierarchy subscriberClassByMethodKey.put(methodKey, methodClassOld); return false; } }
用法参考=>https://greenrobot.org/eventbus/documentation/subscriber-index/
配置好后build项目,build->generated->ap_generated_sources->debug->out->com.example.myapp目录下生成MyEventBusIndex类文件;可以看到,通过apt的process方法,在编译时生成了所有订阅方法
package com.example.myapp; import org.greenrobot.eventbus.meta.SimpleSubscriberInfo; import org.greenrobot.eventbus.meta.SubscriberMethodInfo; import org.greenrobot.eventbus.meta.SubscriberInfo; import org.greenrobot.eventbus.meta.SubscriberInfoIndex; import org.greenrobot.eventbus.ThreadMode; import java.util.HashMap; import java.util.Map; /** This class is generated by EventBus, do not edit. */ public class MyEventBusIndex implements SubscriberInfoIndex { private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX; static { SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>(); putIndex(new SimpleSubscriberInfo(cc.catface.eventbus.MainActivity.class, true, new SubscriberMethodInfo[] { new SubscriberMethodInfo("onName", cc.catface.eventbus.NameMsg.class, ThreadMode.MAIN_ORDERED, 7, true), new SubscriberMethodInfo("onAge", cc.catface.eventbus.AgeMsg.class), new SubscriberMethodInfo("onCommon", cc.catface.eventbus.CommonMsg.class), new SubscriberMethodInfo("onImpl", cc.catface.eventbus.MsgImpl.class), new SubscriberMethodInfo("onI", cc.catface.eventbus.IMsg.class), })); } 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中收集上述在build生成的订阅方法信息
/*根据订阅者类找到所有订阅方法[如根据firstActivity找到onMsg1/onMsg2]*/ private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) { FindState findState = prepareFindState(); //置findState的subscriberClass==clazz=firstActivity findState.initForSubscriber(subscriberClass); //查找firstActivity while (findState.clazz != null) { // findState.subscriberInfo = getSubscriberInfo(findState); if (findState.subscriberInfo != null) { SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods(); for (SubscriberMethod subscriberMethod : array) { if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) { findState.subscriberMethods.add(subscriberMethod); } } } else { findUsingReflectionInSingleClass(findState); } //查找父类 findState.moveToSuperclass(); } return getMethodsAndRelease(findState); }
/*findState中clazz为firstActivity*/ private SubscriberInfo getSubscriberInfo(FindState findState) { //查找父类中的订阅对象[如firstActivity的父类baseActivity] if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) { SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo(); if (findState.clazz == superclassInfo.getSubscriberClass()) { return superclassInfo; } } if (subscriberInfoIndexes != null) { for (SubscriberInfoIndex index : subscriberInfoIndexes) { //调用MyEventBusIndex的getSubscriberInfo方法获取编译时生成的订阅方法索引 SubscriberInfo info = index.getSubscriberInfo(findState.clazz); if (info != null) { return info; } } } return null; }
subscribe(subscriber, subscriberMethod)
如将firstActivity中的onMsg1/onMsg2订阅方法添加至subscribedEvents集合
// Must be called in synchronized block private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) { //订阅事件类型[如Msg1] Class<?> eventType = subscriberMethod.eventType; //创建订阅对象[如new Subscription(firstActivity, onMsg1(msg1))] Subscription newSubscription = new Subscription(subscriber, subscriberMethod); //订阅了Msg1事件的订阅集合subscriptions //一开始是空的 CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType); if (subscriptions == null) { subscriptions = new CopyOnWriteArrayList<>(); //将Msg1和新建的subscriptions空集合信息对放入map中 subscriptionsByEventType.put(eventType, subscriptions); } else { //subscriptions集合中已有当前订阅对象=>异常提示firstActivity已有监听Msg1的订阅方法 if (subscriptions.contains(newSubscription)) { throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event " + eventType); } } int size = subscriptions.size(); for (int i = 0; i <= size; i++) { //根据优先级添加订阅对象至subscriptions if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) { subscriptions.add(i, newSubscription); break; } } //查找订阅者订阅的所有事件类型[如firstActivity订阅的Msg1, Msg2] List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber); //若该订阅者的订阅方法类型列表为空 if (subscribedEvents == null) { //给该订阅者加一个空的订阅的事件类型集合 subscribedEvents = new ArrayList<>(); typesBySubscriber.put(subscriber, subscribedEvents); } //添加订阅的事件类型[如Msg1] subscribedEvents.add(eventType); /** * 粘性事件:事件发送后再订阅该事件也能接收 */ if (subscriberMethod.sticky) { if (eventInheritance) { // Existing sticky events of all subclasses of eventType have to be considered. // Note: Iterating over all events may be inefficient with lots of sticky events, // thus data structure should be changed to allow a more efficient lookup // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>). Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet(); for (Map.Entry<Class<?>, Object> entry : entries) { Class<?> candidateEventType = entry.getKey(); if (eventType.isAssignableFrom(candidateEventType)) { Object stickyEvent = entry.getValue(); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } } else { //根据事件类型获取粘性事件 Object stickyEvent = stickyEvents.get(eventType); //检查并发送粘性事件 checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } }
.unregister(this)
如unregister(firstActivity),根据firstActivity获取typesBySubscriber为[Msg1, Msg2],遍历调用unsubscribeByEventType(firstActivity, [Msg1, Msg2]),调用subscriptionsByEventType.get(Msg1, Msg2),得到的subscriptions分别为[firstActivity]和[firstActivity, secondActivity],然后判断并移除,最后的subscriptions分别为[]和[secondActivity]
/** Unregisters the given subscriber from all event classes. */ public synchronized void unregister(Object subscriber) { //subscribedTypes为subscriber内所有的订阅事件类型[如firstActivity内订阅了Msg1,Msg2] //其中typesBySubscriber在订阅者调用register(this)方法注册后会赋值所以此处才必不为空 List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber); if (subscribedTypes != null) { for (Class<?> eventType : subscribedTypes) { unsubscribeByEventType(subscriber, eventType); } typesBySubscriber.remove(subscriber); } else { //异常提示未注册 logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass()); } }
/** Only updates subscriptionsByEventType, not typesBySubscriber! Caller must update typesBySubscriber. */ private void unsubscribeByEventType(Object subscriber, Class<?> eventType) { //获取所有订阅了事件类型为eventType的订阅者 List<Subscription> subscriptions = subscriptionsByEventType.get(eventType); if (subscriptions != null) { int size = subscriptions.size(); for (int i = 0; i < size; i++) { Subscription subscription = subscriptions.get(i); //将当前订阅者从eventType事件类型的订阅者列表中移除 if (subscription.subscriber == subscriber) { subscription.active = false; subscriptions.remove(i); i--; size--; } } } }
.post(new MessageEvent())
/** Posts the given event to the event bus. */ public void post(Object event) { //currentPostingThreadState是事件信息的队列 PostingThreadState postingState = currentPostingThreadState.get(); List<Object> eventQueue = postingState.eventQueue; //将事件添加至事件队列 eventQueue.add(event); if (!postingState.isPosting) { //检查是否在主线程发送事件 postingState.isMainThread = isMainThread(); //设置事件发送状态 postingState.isPosting = true; if (postingState.canceled) { throw new EventBusException("Internal error. Abort state was not reset"); } try { while (!eventQueue.isEmpty()) { //发送事件 postSingleEvent(eventQueue.remove(0), postingState); } } finally { //重置事件的发送状态 postingState.isPosting = false; postingState.isMainThread = false; } } }
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error { //事件类型[如msg1事件的类型为Msg1] Class<?> eventClass = event.getClass(); boolean subscriptionFound = false; if (eventInheritance) { //如firstActivity中订阅了Msg1事件/Msg1的父类如BaseMsg事件/Msg1的接口如IMsg事件的订阅方法都会接受事件 //如有事件Msg1 extends BaseMsg implements IMsg //在firstActivity中有订阅方法onMsg1(Msg1)/onBaseMsg(BaseMsg)/onIMsg(IMsg) //此时post(Msg1)则firstActivity中的三个订阅方法都会回调 List<Class<?>> eventTypes = lookupAllEventTypes(eventClass); int countTypes = eventTypes.size(); for (int h = 0; h < countTypes; h++) { Class<?> clazz = eventTypes.get(h); //发送event事件 subscriptionFound |= postSingleEventForEventType(event, postingState, clazz); } } else { subscriptionFound = postSingleEventForEventType(event, postingState, eventClass); } //没有订阅event事件的订阅方法 if (!subscriptionFound) { if (logNoSubscriberMessages) { logger.log(Level.FINE, "No subscribers registered for event " + eventClass); } if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) { post(new NoSubscriberEvent(this, event)); } } }
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) { CopyOnWriteArrayList<Subscription> subscriptions; synchronized (this) { //订阅了Msg1事件的订阅方法[如onMsg1/onBaseMsg/onIMsg] subscriptions = subscriptionsByEventType.get(eventClass); } if (subscriptions != null && !subscriptions.isEmpty()) { for (Subscription subscription : subscriptions) { postingState.event = event; postingState.subscription = subscription; boolean aborted; try { //将事件发送给订阅对象[如(firstActivity, onMsg1(msg1)-main), msg1, msg1事件post的线程在thread] postToSubscription(subscription, event, postingState.isMainThread); aborted = postingState.canceled; } finally { //重置状态 postingState.event = null; postingState.subscription = null; postingState.canceled = false; } if (aborted) { break; } } return true; } return false; }
//[如(firstActivity, onMsg1(msg1)-main), msg1, msg1事件post的线程在thread] private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) { switch (subscription.subscriberMethod.threadMode) { case POSTING: invokeSubscriber(subscription, event); break; case MAIN: if (isMainThread) { //若onMsg1(msg1)订阅方法被定义在main线程处理且msg1事件发送线程也在main线程 //反射调用方法[如onMsg1.invoke(firstActivity, msg1)] invokeSubscriber(subscription, event); } else { //若onMsg1(msg1)订阅方法被定义在main线程处理且msg1事件发送线程在子线程=>Handler线程调度 mainThreadPoster.enqueue(subscription, event); } break; case MAIN_ORDERED: if (mainThreadPoster != null) { mainThreadPoster.enqueue(subscription, event); } else { // temporary: technically not correct as poster not decoupled from subscriber invokeSubscriber(subscription, event); } break; case BACKGROUND: if (isMainThread) { backgroundPoster.enqueue(subscription, event); } else { invokeSubscriber(subscription, event); } break; case ASYNC: asyncPoster.enqueue(subscription, event); break; default: throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode); } }
反射调用订阅了event事件的订阅方法
void invokeSubscriber(Subscription subscription, Object event) { try { //反射调用方法 subscription.subscriberMethod.method.invoke(subscription.subscriber, event); } catch (InvocationTargetException e) { handleSubscriberException(subscription, event, e.getCause()); } catch (IllegalAccessException e) { throw new IllegalStateException("Unexpected exception", e); } }
粘性:即可以先post发送事件,在post后注册的订阅方法也可以接收到事件(从消息缓存中获取已发送的事件),并开始消费
EventBus.getDefault().postSticky(new Msg());
public void postSticky(Object event) { synchronized (stickyEvents) { //缓存粘性事件 stickyEvents.put(event.getClass(), event); } // Should be posted after it is putted, in case the subscriber wants to remove immediately post(event); }
若当前订阅方法被声明为粘性,则在订阅后立即执行
// Must be called in synchronized block private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) { //... //当前订阅方法是粘性属性,直接调用该订阅方法 if (subscriberMethod.sticky) { if (eventInheritance) { // Existing sticky events of all subclasses of eventType have to be considered. // Note: Iterating over all events may be inefficient with lots of sticky events, // thus data structure should be changed to allow a more efficient lookup // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>). Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet(); for (Map.Entry<Class<?>, Object> entry : entries) { Class<?> candidateEventType = entry.getKey(); if (eventType.isAssignableFrom(candidateEventType)) { Object stickyEvent = entry.getValue(); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } } else { Object stickyEvent = stickyEvents.get(eventType); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } }