简谈源码-EventBus(v3.2.0)
作者:互联网
使用方法
步骤一、定义事件
订阅的事件类
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事件的订阅方法;
源码走读
1.订阅注解@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;
}
2.创建EventBus实例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;
}
//...
}
3.EventBus的注册.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);
}
}
}
3.1找出订阅者内的所有订阅方法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;
}
}
3.1.1方式一、反射
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;
}
}
3.1.2方式二、索引
用法参考=>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;
}
3.2事件订阅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);
}
}
}
EventBus的反注册.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--;
}
}
}
}
EventBus发送事件.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);
}
}
}
标签:v3.2,订阅,eventType,简谈,findState,源码,new,null,event 来源: https://blog.csdn.net/itCatface/article/details/121266190