(1)eventbus的使用
为了方便分析EventBus的源码,这里我们先整个demo出来,源码如下:
public class MainActivity extends AppCompatActivity {
private TextView tvMessage;
private View btnSecond;
private Button btnRegister;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
tvMessage = findViewById(R.id.tv_message);
btnSecond = findViewById(R.id.btn_second);
btnRegister = findViewById(R.id.tv_register);
btnRegister.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
}
});
btnSecond.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
loadData("http://www.baidu.com");
}
public void loadData(final String url){
new Thread(){
@Override
public void run() {
super.run();
String json = "message from MainActivity";
MessageEvent messageEvent = new MessageEvent("recode",json,"msg");
//在子线程当中发布类给主线程
// EventBus.getDefault().post(json);
EventBus.getDefault().post(messageEvent);
}
}.start();
}
// @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)//MAIN代表主线程
@Subscribe(threadMode = ThreadMode.MAIN,sticky = false)
public void receiveMessage(MessageEvent messageEvent){//该方法名可更改,不影响任何东西。
//在主线程中获取子线程发送来的消息设置到TextView中
tvMessage.setText(messageEvent.getResult());
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
(2)EventBus的register过程
- EventBus的初始化
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
可以看出:EventBus调用getDefault方法进行初始化,并且使用了双重否定的单例模式。
- EventBus调用register方法进行事件订阅
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
- Subscriber:订阅者对象,对应demo中的MainActivity
- SubscriberMethod:是我们在Activity中定义的订阅方法的一个描述类,里面保存了订阅方法的信息,其实就是我们在Activity中定义的用@Subscriber注解修饰的receiveMessage(MessageEvent)方法。这里我截取了SubscriberMethod的成员变量信息,如下所示:
public SubscriberMethod(Method method, Class<?> eventType, ThreadMode threadMode, int priority, boolean sticky) {
this.method = method;
this.threadMode = threadMode;
this.eventType = eventType;
this.priority = priority;
this.sticky = sticky;
}
method:方法名
ThreadMode:注解名称
eventType:消息类型的字节码对象,对应demo中MessageEvent的class对象
priority:注解中priority属性,表示方法执行的优先级
- EventBus是如何找到subscriberMethod的集合的呢?
subscriberMethodFinder调用findSubscriberMethods(subscriberClass)方法找到了Subscriber对象(MainActivity)中所有订阅方法信息的集合。
那么findSubscriberMethods是如何找到SubscriberMethod的呢?
我们接着往下看SubscriberMethodFinder的findSubscriberMethods方法,代码如下所示:
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
//利用反射来获取订阅类中的订阅方法信息
if (ignoreGeneratedIndex) {
subscriberMethods = findUsingReflection(subscriberClass);
} else {
//通过注解来获取订阅方法信息
subscriberMethods = findUsingInfo(subscriberClass);
}
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;
}
}
- METHOD_CACHE:EventBus对Subscriber订阅者的订阅方法做的一个缓存,它是一个Map对象,key是Subscriber对象,因为Subscriber对象可能有多个订阅方法,所以value是Subscriber对应的订阅方法的集合。
可以看出EventBus先会从缓存中拿Subscriber对应的SubscriberMethod的集合,如果缓存不为空,直接从缓存中获取。
- ignoreGeneratedIndex:这个参数默认是为false,表示使用@Subscribe注解,EventBus3.0版本后默认使用该注解来表示订阅方法。而在EventBus3.0之前只能使用写死的方法定义订阅方法,这样非常容易出错。真正的获取订阅方法集合的方法其实是findUsingInfo(subscriberClass)方法。
findUsingInfo的源码如下所示:
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
FindState findState = prepareFindState();
findState.initForSubscriber(subscriberClass);
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);
}
首先会执行prepareFindState方法去获取FindState,代码如下:
private FindState prepareFindState() {
synchronized (FIND_STATE_POOL) {
for (int i = 0; i < POOL_SIZE; i++) {
FindState state = FIND_STATE_POOL[i];
if (state != null) {
FIND_STATE_POOL[i] = null;
return state;
}
}
}
return new FindState();
}
FIND_STATE_POOL:是一个最近使用且长度为4的FindState数组,目的是用来EventBus缓存FindState信息,提升eventBus的运行效率的。
- FindState对象是什么?
static class FindState {
final List<SubscriberMethod> subscriberMethods = new ArrayList<>();
final Map<Class, Object> anyMethodByEventType = new HashMap<>();
final Map<String, Class> subscriberClassByMethodKey = new HashMap<>();
final StringBuilder methodKeyBuilder = new StringBuilder(128);
Class<?> subscriberClass;
Class<?> clazz;
boolean skipSuperClasses;
SubscriberInfo subscriberInfo;
}
开始我也有点懵逼,各种类傻傻分不清,但是我们打个断点就什么都明白了,其实FindState类就是一个保存将要查找的订阅方法信息的类。其主要成员变量如下:
-
subscriberMethods :SubScriber订阅者(对应demo中MainActivity)的所有订阅方法的集合。
-
anyMethodByEventType :一个用来保存eventType(对应demo中的EventMessage)和其对应的method。
-
subscriberClassByMethodKey :一个map对象,key是一个订阅方法名称和EventType参数构成的字符串,value为订阅方法的class对象。
-
subscriberClass和class:订阅者类的class字节码对象
-
如何获取subscriber的订阅方法?
private SubscriberInfo getSubscriberInfo(FindState findState) {
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) {
SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
if (info != null) {
return info;
}
}
}
return null;
}
subscriberInfoIndexes 不为空会调用getSubscriberInfo方法获取SubscriberInfo对象,SubscriberInfo对象包括了Subscriber和订阅方法的信息。后面我们发现SubscriberInfo是通过index.getSubscriberInfo()方法来得到的。那么index指的是什么呢?
3.0版本中,EventBus提供了一个EventBusAnnotationProcessor注解处理器来在编译期通过读取@Subscribe()注解并解析,
处理其中所包含的信息,然后生成java类来保存所有订阅者关于订阅的信息,这样就比在运行时使用反射来获得这些订阅者的
信息速度要快.我们可以参考EventBus项目里的EventBusPerformance这个例子,编译后我们可以在build文件夹里找到这个类MyEventBusIndex 类,前面的index就属于MyEventBusIndex对象类型
建议用git拉下EventBus的源码,然后搜索EventBusAnnotationProcessor这个类,其源码比较多,这里我们看看它的createInfoIndexFile方法,其源码如下所示:
private void createInfoIndexFile(String index) {
BufferedWriter writer = null;
try {
JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(index);
int period = index.lastIndexOf('.');
String myPackage = period > 0 ? index.substring(0, period) : null;
String clazz = index.substring(period + 1);
writer = new BufferedWriter(sourceFile.openWriter());
if (myPackage != null) {
writer.write("package " + myPackage + ";\n\n");
}
writer.write("import org.greenrobot.eventbus.meta.SimpleSubscriberInfo;\n");
writer.write("import org.greenrobot.eventbus.meta.SubscriberMethodInfo;\n");
writer.write("import org.greenrobot.eventbus.meta.SubscriberInfo;\n");
writer.write("import org.greenrobot.eventbus.meta.SubscriberInfoIndex;\n\n");
writer.write("import org.greenrobot.eventbus.ThreadMode;\n\n");
writer.write("import java.util.HashMap;\n");
writer.write("import java.util.Map;\n\n");
writer.write("/** This class is generated by EventBus, do not edit. */\n");
writer.write("public class " + clazz + " implements SubscriberInfoIndex {\n");
writer.write(" private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;\n\n");
writer.write(" static {\n");
writer.write(" SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();\n\n");
writeIndexLines(writer, myPackage);//把用了Subscriber注解的方法和方法所在的类信息拼凑起来
writer.write(" }\n\n");
writer.write(" private static void putIndex(SubscriberInfo info) {\n");
writer.write(" SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);\n");
writer.write(" }\n\n");
writer.write(" @Override\n");
writer.write(" public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {\n");
writer.write(" SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);\n");
writer.write(" if (info != null) {\n");
writer.write(" return info;\n");
writer.write(" } else {\n");
writer.write(" return null;\n");
writer.write(" }\n");
writer.write(" }\n");
writer.write("}\n");
} catch (IOException e) {
throw new RuntimeException("Could not write source for " + index, e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
//Silent
}
}
}
}
createInfoIndexFile方法其实就是在创建一个MyEventBusIndex.class文件,其中writeIndexLines方法是在把用了Subscriber注解的方法和方法所在的类信息拼凑起来,writeIndexLines方法的源码如下所示:
private void writeIndexLines(BufferedWriter writer, String myPackage) throws IOException {
for (TypeElement subscriberTypeElement : methodsByClass.keySet()) {
if (classesToSkip.contains(subscriberTypeElement)) {
continue;
}
String subscriberClass = getClassString(subscriberTypeElement, myPackage);
if (isVisible(myPackage, subscriberTypeElement)) {
writeLine(writer, 2,
"putIndex(new SimpleSubscriberInfo(" + subscriberClass + ".class,",
"true,", "new SubscriberMethodInfo[] {");
List<ExecutableElement> methods = methodsByClass.get(subscriberTypeElement);
writeCreateSubscriberMethods(writer, methods, "new SubscriberMethodInfo", myPackage);
writer.write(" }));\n\n");
} else {
writer.write(" // Subscriber not visible to index: " + subscriberClass + "\n");
}
}
}
下面再来看看EventBusAnnotationProcessor注解处理类生成的MyEventBusIndex这个类都长什么样吧,可以通过build EventBusPerformance这个model来生成它。
public class MyEventBusIndex implements SubscriberInfoIndex {
private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;
static {
SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();
putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscribeClassEventBusMainOrdered.class,
true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onEvent", TestEvent.class, ThreadMode.MAIN_ORDERED),
}));
putIndex(new SimpleSubscriberInfo(TestRunnerActivity.class, true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onEventMainThread", TestFinishedEvent.class, ThreadMode.MAIN),
}));
putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscribeClassEventBusBackground.class,
true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onEventBackgroundThread", TestEvent.class, ThreadMode.BACKGROUND),
}));
putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscribeClassEventBusMain.class,
true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onEventMainThread", TestEvent.class, ThreadMode.MAIN),
}));
putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.SubscribeClassEventBusDefault.class,
true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onEvent", TestEvent.class),
}));
putIndex(new SimpleSubscriberInfo(org.greenrobot.eventbusperf.testsubject.PerfTestEventBus.SubscriberClassEventBusAsync.class,
true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onEventAsync", TestEvent.class, ThreadMode.ASYNC),
}));
}
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;
}
}
}
可以看出MyEventBusIndex这个类已经把我们定义的订阅方法信息全都用一个map保存起来了,key为Subscriber的字节码类,value为订阅方法信息类。后面也就不奇怪,我们可以通过迭代直接得到订阅方法的信息了。
如果EventBus没有拿到MyEventBusIndex对象携带的订阅方法信息的话,那么将通过Subscriber对象手动解析带有@subscribe注解的订阅方法,当然这种方法效率太低了,其实是一种容错处理。这个解析过程便是通过findUsingReflectionInSingleClass实现的,如下所示:
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
methods = findState.clazz.getMethods();
findState.skipSuperClasses = true;
}
for (Method method : methods) {
int modifiers = method.getModifiers();
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) {
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) {
Class<?> eventType = parameterTypes[0];
if (findState.checkAdd(method, eventType)) {
ThreadMode threadMode = subscribeAnnotation.threadMode();
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
}
}
} 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);
}
} 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");
}
}
}
- 订阅方法注册过程
前面我们拿到了订阅方法以及订阅对象的信息后,并保持在SubscriberMethod集合中,后面会迭代这个集合,然后依次执行subscribe方法。subscribe方法的源码如下所示:
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
Class<?> eventType = subscriberMethod.eventType;
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
} else {
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++) {
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
subscriptions.add(i, newSubscription);
break;
}
}
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
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);
}
}
}
subscribe()方法其实主要就干了这么几件事:
-
对消息进行优先级排序
-
缓存subscriber method的信息
subscriptionsByEventType这个Map对象的值就是用来缓存订阅方法的信息的,其中key为EventType的class对象,value为Subscription对象的集合,而Subscription对象的成员变量就是订阅者对象Subscriber以及订阅方法SubscriberMethod,这个map对象在后面发送消息时会用到,当要发送消息时,其实就是迭代这个对象,然后利用发射执行订阅方法。 -
如果有sticky消息,直接发送。也可以得知sticky消息在注册后是可以
执行的。
整个注册的大致流程如下:
eventbus注册流程.png(2)发送消息和接收消息
由于sticky消息的发送最终也是执行post方法,这里只拿post方法来做分析,EventBus的post方法的源码如下所示:
public void post(Object event) {
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;
}
}
}
这个方法主要用来,判断消息是否已经发送,方法执行到底是否在主线程中,消息是否已经取消,并且用EventType保存了如果符合要求,则程序继续往下执行postSingleEvent方法,然后是各种判断,接着会执行postSingleEventForEventType方法其源码如下所示:
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
CopyOnWriteArrayList<Subscription> subscriptions;
synchronized (this) {
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
for (Subscription subscription : subscriptions) {
postingState.event = event;
postingState.subscription = subscription;
boolean aborted = false;
try {
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;
}
这个方法会拿出注册时缓存订阅方法的相关信息subscriptionsByEventType,并迭代这个Map对象,取出订阅方法的信息,并最终执行postToSubscription方法,该方法的源码如下所示:
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
switch (subscription.subscriberMethod.threadMode) {
case POSTING:
invokeSubscriber(subscription, event);
break;
case MAIN:
if (isMainThread) {
invokeSubscriber(subscription, event);
} else {
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);
}
}
看到这里是不是有种似曾相识的感觉呢?没错就是根据注解中threadMode的值,判断方法在哪个线程中执行,无论是在主线程还是子线程中执行,最终都会invokeSubscriber方法,其实就是利用发射执行Subscriber method,所以EventBus的post()方法执行后,最终会执行Subscriber method。
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);
}
}
-
POSTING:Subscriber和Subscriber Method在同一个线程中执行
-
MAIN:Subscriber Method将在主线程中执行,如果在主线程中直接执行Subscriber Method,如果在子线程中使用handler进行消息发送,并在主线程中执行。
-
MAIN_ORDERED:主线程中按顺序执行Subscriber Method。
-
BACKGROUND:如果post方法发送消息在子线程中,那么直接执行Subscriber method;如果post方法发送消息是在主线程中,将会在子线程中执行Subscriber method。
-
ASYNC:无论是在主线程还是子线程中发送消息,那么都讲会子线程中执行Subscriber method
EventBus发送消息的过程.png
(3) EventBus unRegister过程
unregister方法的源码如下:
/** Unregisters the given subscriber from all event classes. */
public synchronized void unregister(Object subscriber) {
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());
}
}
把之前Subscriber注册时保存下来的订阅方法信息删除,然后执行
unsubscribeByEventType方法,其代码如下所示:
private void unsubscribeByEventType(Object subscriber, Class<?> 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);
if (subscription.subscriber == subscriber) {
subscription.active = false;
subscriptions.remove(i);
i--;
size--;
}
}
}
}
循环查找subScription对象并把它的active属性改成false,最后删除subscription对象。
---------------end-----------------
如果文章对你有帮助的话,记得点一个赞哦。
网友评论