文章目录
- 介绍
- 优点
- 基本用法
- 线程模式
- POSTING
- MAIN
- MAIN_ORDERED
- BACKGROUND
- ASYNC
- 黏性事件
- 源码
- 注册
- getDefault()
- register
- findSubscriberMethods
- 小结
- post
- postSticky
- unregister
介绍
优点
- 简化组件之间的通信
- 解耦事件发送者和接收者
- 在 Activity、Fragment 和后台线程中表现良好
- 避免复杂且容易出错的依赖关系和生命周期问题
- 让你的代码更简单
- 很快,很小
- 具有高级功能,如交付线程、订阅者优先级等。
基本用法
导入依赖
implementation "org.greenrobot:eventbus:3.3.1"
- 定义事件:
public static class MessageEvent { /* Additional fields if needed */ }
-
准备订阅者:声明并注释您的订阅方法,可以选择指定线程模式
@Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MessageEvent event) {// Do something }
注册和取消注册您的订户。例如在 Android 上,活动和片段通常应根据其生命周期进行注册:
@Overridepublic void onStart() {super.onStart();EventBus.getDefault().register(this);}@Overridepublic void onStop() {super.onStop();EventBus.getDefault().unregister(this);}
-
发布活动:
EventBus.getDefault().post(new MessageEvent());
线程模式
POSTING
- 特点:订阅者在发布事件的同一线程中被调用。
- 优点:开销最小,避免了线程切换。
- 适用场景:已知任务简单且快速完成,不依赖主线程。
- 注意:长时间任务可能阻塞发布线程(如是主线程,会导致UI卡顿)。
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(MessageEvent event) {log(event.message); // 快速返回的简单任务
}
MAIN
-
特点:
- 订阅者在主线程(UI线程)中被调用
- 如果发布线程为主线程,则同步调用(与
POSTING
类似)
-
适用场景:UI更新或需要在主线程完成的轻量任务。
-
注意:避免执行耗时任务,否则会阻塞主线程,导致卡顿。
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {textView.setText(event.message); // 更新UI
}
MAIN_ORDERED
- 特点:
- 在主线程中执行。
- 按顺序执行:事件会一个接一个地处理,不会乱序。
- 适用场景:依赖特定执行顺序的UI更新逻辑。
- 注意:与
MAIN
类似,避免耗时任务,确保任务快速返回。
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMessageEvent(String event) {Log.d("EventBus", "Event received: " + event); // 按顺序更新UI
}
BACKGROUND
- 特点:
- 如果发布线程为主线程,事件处理方法会切换到后台线程。
- 如果发布线程是非主线程,事件处理方法直接在发布线程中执行。
- 适用场景:后台任务,如数据库存储、文件操作。
- 注意:快速返回,避免阻塞后台线程。
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEvent event) {saveToDisk(event.message); // 后台存储操作
}
ASYNC
- 特点:事件处理程序始终在独立线程中调用,与发布线程或主线程完全分离。
- 适用场景:耗时操作,如网络请求、复杂计算。
- 注意:避免触发大量异步任务,防止线程池耗尽资源。
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessage(MessageEvent event) {backend.send(event.message); // 异步网络请求
}
黏性事件
发送事件之后再订阅也能收到该事件
@Subscribe(threadMode = ThreadMode.POSTING, sticky = true)
public void onMessageEvent(MessageEvent messageEvent) {tv.setText(messageEvent.getMessage());
}
EventBus.getDefault().postSticky(new MessageEvent("SecondActivity的信息"));
源码
注册
getDefault()
public class EventBus {// 静态变量,存储唯一的 EventBus 实例// 使用 volatile 关键字,确保多线程环境下变量的可见性和防止指令重排static volatile EventBus defaultInstance;public static EventBus getDefault() {// 将静态变量 defaultInstance 赋值给局部变量 instance,减少对主内存的访问EventBus instance = defaultInstance;// 第一次检查,避免不必要的同步开销if (instance == null) {// 如果实例未被初始化,进入同步块synchronized (EventBus.class) {// 再次将 defaultInstance 的值赋给 instance(看这个时候defaultInstance为不为空)instance = EventBus.defaultInstance;// 第二次检查,确保实例仍未被初始化(双重检查锁定)if (instance == null) {// 创建新的 EventBus 实例并赋值给 defaultInstance 和局部变量 instanceinstance = EventBus.defaultInstance = new EventBus();}}}return instance;}
}
public EventBus() {this(DEFAULT_BUILDER);
}
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
EventBus(EventBusBuilder builder) {//日志logger = builder.getLogger();//这个集合可以根据事件类型获取订阅者//key:事件类型,value:订阅该事件的订阅者集合subscriptionsByEventType = new HashMap<>();//订阅者所订阅的事件集合//key:订阅者,value:该订阅者订阅的事件集合typesBySubscriber = new HashMap<>();//粘性事件集合//key:事件Class对象,value:事件对象stickyEvents = new ConcurrentHashMap<>();//Android主线程处理事件mainThreadSupport = builder.getMainThreadSupport();mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;//Background事件发送者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;
}
这个方法内部首先通过单例模式创建一个EventBus
对象,在创建EventBus
时最终会调用它的有参构造函数,传入一个EventBus.Builder
对象。在这个有参构造函数内部对属性进行初始化
register
public class EventBus {public void register(Object subscriber) {// 1、通过反射获取到订阅者的Class对象Class<?> subscriberClass = subscriber.getClass();// 2、通过subscriberMethodFinder对象获取订阅者所订阅事件的集合List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);synchronized (this) {// 3、遍历集合进行注册for (SubscriberMethod subscriberMethod : subscriberMethods) {subscribe(subscriber, subscriberMethod);}}}private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {// 4、获取事件类型Class<?> eventType = subscriberMethod.eventType;// 5、封装Subscription对象Subscription newSubscription = new Subscription(subscriber, subscriberMethod);// 6、通过事件类型获取该事件的订阅者集合CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);// 7、如果没有订阅者订阅该事件if (subscriptions == null) {// 创建集合,存入subscriptionsByEventType集合中subscriptions = new CopyOnWriteArrayList<>();subscriptionsByEventType.put(eventType, subscriptions);} else { // 8、如果有订阅者已经订阅了该事件// 判断这些订阅者中是否有重复订阅的现象if (subscriptions.contains(newSubscription)) {throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "+ eventType);}}int size = subscriptions.size();// 9、遍历该事件的所有订阅者for (int i = 0; i <= size; i++) {// 按照优先级高低进行插入,如果优先级最低,插入到集合尾部if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {subscriptions.add(i, newSubscription);break;}}// 10、获取该事件订阅者订阅的所有事件集合List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);if (subscribedEvents == null) {subscribedEvents = new ArrayList<>();typesBySubscriber.put(subscriber, subscribedEvents);}// 11、将该事件加入到集合中subscribedEvents.add(eventType);// 12、判断该事件是否是粘性事件if (subscriberMethod.sticky) {if (eventInheritance) { // 13、判断事件的继承性,默认是不可继承// 14、获取所有粘性事件并遍历,判断继承关系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();// 15、调用checkPostStickyEventToSubscription方法checkPostStickyEventToSubscription(newSubscription, stickyEvent);}}} else {Object stickyEvent = stickyEvents.get(eventType);checkPostStickyEventToSubscription(newSubscription, stickyEvent);}}}private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {if (stickyEvent != null) {// 16、如果粘性事件不为空postToSubscription(newSubscription, stickyEvent, isMainThread());}}private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {// 17、根据threadMode的类型去选择是直接反射调用方法,还是将事件插入队列switch (subscription.subscriberMethod.threadMode) {case POSTING:invokeSubscriber(subscription, event);break;case MAIN:if (isMainThread) {// 18、通过反射的方式调用invokeSubscriber(subscription, event);} else {// 19、将粘性事件插入到队列中// 最后还是会调用EventBus.invokeSubscriber(PendingPost pendingPost)方法。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 subscriberinvokeSubscriber(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);}}void invokeSubscriber(PendingPost pendingPost) {Object event = pendingPost.event;Subscription subscription = pendingPost.subscription;PendingPost.releasePendingPost(pendingPost);if (subscription.active) {invokeSubscriber(subscription, 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);}}
}public class SubscriberMethod {final Method method; // 处理事件的Method对象final ThreadMode threadMode; //线程模型final Class<?> eventType; //事件类型final int priority; //事件优先级final boolean sticky; //是否是粘性事件String methodString;
}final class Subscription {final Object subscriber;final SubscriberMethod subscriberMethod;
}
findSubscriberMethods
class SubscriberMethodFinder {private static final int MODIFIERS_IGNORE = Modifier.ABSTRACT | Modifier.STATIC | BRIDGE | SYNTHETIC;private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();private static final int POOL_SIZE = 4;private static final FindState[] FIND_STATE_POOL = new FindState[POOL_SIZE];List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {// 1、先从之前缓存的集合中获取List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);if (subscriberMethods != null) {// 2、如果之前缓存了,直接返回return subscriberMethods;}if (ignoreGeneratedIndex) { //ignoreGeneratedIndex一般为falsesubscriberMethods = findUsingReflection(subscriberClass);} else {// 3、获取所有订阅方法集合subscriberMethods = findUsingInfo(subscriberClass);}if (subscriberMethods.isEmpty()) {throw new EventBusException("Subscriber " + subscriberClass+ " and its super classes have no public methods with the @Subscribe annotation");} else {// 4、放入缓存集合中METHOD_CACHE.put(subscriberClass, subscriberMethods);return subscriberMethods;}}private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {// 5、从数组中获取FindState对象// 如果有直接返回,如果没有创建一个新的FindState对象FindState findState = prepareFindState();// 6、根据事件订阅者初始化findStatefindState.initForSubscriber(subscriberClass);while (findState.clazz != null) {// 7、获取subscriberInfo,初始化为nullfindState.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 {// 8、通过反射的方式获取订阅者中的Method,默认情况findUsingReflectionInSingleClass(findState);}findState.moveToSuperclass();}return getMethodsAndRelease(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();}private void findUsingReflectionInSingleClass(FindState findState) {Method[] methods;try {// 9、订阅者中所有声明的方法,放入数组中methods = findState.clazz.getDeclaredMethods();} catch (Throwable th) {// 10、获取订阅者中声明的public方法,设置跳过父类methods = findState.clazz.getMethods();findState.skipSuperClasses = true;}// 遍历这些方法for (Method method : methods) {// 11、获取方法的修饰符:public、private等等int modifiers = method.getModifiers();// 12、订阅方法为public同时不是abstract、staticif ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {// 13、方法参数类型数组Class<?>[] parameterTypes = method.getParameterTypes();if (parameterTypes.length == 1) {// 14、获取方法的注解Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);// 15、如果有注解if (subscribeAnnotation != null) {Class<?> eventType = parameterTypes[0];// 16、将method和eventType放入到findState进行检查if (findState.checkAdd(method, eventType)) {// 17、获取注解中的threadMode对象ThreadMode threadMode = subscribeAnnotation.threadMode();// 18、新建一个SubscriberMethod对象,同时加入到findState中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");}}}// 从findState中获取订阅者所有方法并释放private List<SubscriberMethod> getMethodsAndRelease(FindState findState) {// 获取订阅者所有订阅方法集合List<SubscriberMethod> subscriberMethods = new ArrayList<>(findState.subscriberMethods);// findState进行回收findState.recycle();synchronized (FIND_STATE_POOL) {for (int i = 0; i < POOL_SIZE; i++) {if (FIND_STATE_POOL[i] == null) {FIND_STATE_POOL[i] = findState;break;}}}// 返回集合return subscriberMethods;}
}
小结
- 根据单例设计模式创建一个
EventBus
对象,同时创建一个EventBus.Builder
对象对EventBus
进行初始化,其中有三个比较重要的集合和一个SubscriberMethodFinder
对象。 - 调用
register
方法,首先通过反射获取到订阅者的Class
对象。 - 通过
SubscriberMethodFinder
对象获取订阅者中所有订阅的事件集合,它先从缓存中获取,如果缓存中有,直接返回;如果缓存中没有,通过反射的方式去遍历订阅者内部被注解的方法,将这些方法放入到集合中进行返回。 - 遍历第三步获取的集合,将订阅者和事件进行绑定。
- 在绑定之后会判断绑定的事件是否是粘性事件,如果是粘性事件,直接调用
postToSubscription
方法,将之前发送的粘性事件发送给订阅者。
post
public class EventBus {...public void post(Object event) {// 1、获取当前线程的PostingThreadState,这是一个ThreadLocal对象PostingThreadState postingState = currentPostingThreadState.get();// 2、当前线程的事件集合List<Object> eventQueue = postingState.eventQueue;// 3、将要发送的事件加入到集合中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 {// 4、只要事件集合中还有事件,就一直发送while (!eventQueue.isEmpty()) {postSingleEvent(eventQueue.remove(0), postingState);}} finally {postingState.isPosting = false;postingState.isMainThread = false;}}}// currentPostingThreadState是包含了PostingThreadState的ThreadLocal对象// ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据, 并且线程之间的数据是相互独立的。// 其内部通过创建一个它包裹的泛型对象的数组,不同的线程对应不同的数组索引,每个线程通过get方法获取对应的线程数据。private final ThreadLocal<PostingThreadState> currentPostingThreadState = new ThreadLocal<PostingThreadState>() {@Overrideprotected PostingThreadState initialValue() {return new PostingThreadState();}};// 每个线程中存储的数据final static class PostingThreadState {final List<Object> eventQueue = new ArrayList<>(); // 线程的事件队列boolean isPosting; //是否正在发送中boolean isMainThread; //是否在主线程中发送Subscription subscription; //事件订阅者和订阅事件的封装Object event; //事件对象boolean canceled; //是否被取消发送}...private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {// 5、获取事件的Class对象Class<?> eventClass = event.getClass();boolean subscriptionFound = false;if (eventInheritance) { // eventInheritance一般为true// 6、 找到当前的event的所有 父类和实现的接口 的class集合List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);int countTypes = eventTypes.size();for (int h = 0; h < countTypes; h++) {Class<?> clazz = eventTypes.get(h);// 7、遍历集合发送单个事件subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);}} else {subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);}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 static List<Class<?>> lookupAllEventTypes(Class<?> eventClass) {synchronized (eventTypesCache) {// 获取事件集合List<Class<?>> eventTypes = eventTypesCache.get(eventClass);if (eventTypes == null) { //如果为空eventTypes = new ArrayList<>();Class<?> clazz = eventClass;while (clazz != null) {eventTypes.add(clazz); //添加事件addInterfaces(eventTypes, clazz.getInterfaces()); //添加当前事件的接口classclazz = clazz.getSuperclass();// 获取当前事件的父类}eventTypesCache.put(eventClass, eventTypes);}return eventTypes;}}//循环添加当前事件的接口classstatic void addInterfaces(List<Class<?>> eventTypes, Class<?>[] interfaces) {for (Class<?> interfaceClass : interfaces) {if (!eventTypes.contains(interfaceClass)) {eventTypes.add(interfaceClass);addInterfaces(eventTypes, interfaceClass.getInterfaces());}}}private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {CopyOnWriteArrayList<Subscription> subscriptions;synchronized (this) {// 8、根据事件获取所有订阅它的订阅者subscriptions = subscriptionsByEventType.get(eventClass);}if (subscriptions != null && !subscriptions.isEmpty()) {// 9、遍历集合for (Subscription subscription : subscriptions) {postingState.event = event;postingState.subscription = subscription;boolean aborted = false;try {// 10、将事件发送给订阅者postToSubscription(subscription, event, postingState.isMainThread);aborted = postingState.canceled;} finally {// 11、重置postingStatepostingState.event = null;postingState.subscription = null;postingState.canceled = false;}if (aborted) {break;}}return true;}return false;}private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {// 12、根据订阅方法的线程模式调用订阅方法switch (subscription.subscriberMethod.threadMode) {case POSTING: //默认类型,表示发送事件操作直接调用订阅者的响应方法,不需要进行线程间的切换invokeSubscriber(subscription, event);break;case MAIN: //主线程,表示订阅者的响应方法在主线程进行接收事件if (isMainThread) { //如果发送者在主线程invokeSubscriber(subscription, event);//直接调用订阅者的响应方法} else { //如果事件的发送者不是主线程//添加到mainThreadPoster的队列中去,在主线程中调用响应方法mainThreadPoster.enqueue(subscription, event); }break;case MAIN_ORDERED:// 主线程优先模式if (mainThreadPoster != null) {mainThreadPoster.enqueue(subscription, event);} else {//如果不是主线程就在消息发送者的线程中进行调用响应方法invokeSubscriber(subscription, event);}break;case BACKGROUND:if (isMainThread) {// 如果事件发送者在主线程,加入到backgroundPoster的队列中,在线程池中调用响应方法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);}}...
}
- 获取当前线程的事件集合,将要发送的事件加入到集合中。
- 通过循环,只要事件集合中还有事件,就一直发送。
- 获取事件的
Class
对象,找到当前的event
的所有父类和实现的接口的class
集合。遍历这个集合,调用发送单个事件的方法进行发送。 - 根据事件获取所有订阅它的订阅者集合,遍历集合,将事件发送给订阅者。
- 发送给订阅者时,根据订阅方法的线程模式调用订阅方法,如果需要线程切换,则切换线程进行调用;否则,直接调用。
postSticky
EventBus.getDefault().postSticky(Object event)
public class EventBus {public void postSticky(Object event) {synchronized (stickyEvents) {// 1、将事件添加到粘性事件集合中stickyEvents.put(event.getClass(), event);}// 2、发送事件post(event);}
}
- 将粘性事件加入到
EventBus
对象的粘性事件集合中,当有新的订阅者进入后,如果该订阅者订阅了该粘性事件,可以直接发送给订阅者。- 将粘性事件发送给已有的事件订阅者。
unregister
EventBus.getDefault().unregister(Object subscriber)
解注册的方法。
public class EventBus {...public synchronized void unregister(Object subscriber) {// 1、获取订阅者订阅的所有事件List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);if (subscribedTypes != null) {// 2、遍历集合for (Class<?> eventType : subscribedTypes) {// 3、将该订阅者的从订阅该事件的所有订阅者集合中移除unsubscribeByEventType(subscriber, eventType);}// 4、将订阅者从集合中移除typesBySubscriber.remove(subscriber);} else {logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass());}}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--;}}}}...
}
1、获取订阅者的所有订阅方法,遍历这些方法。然后拿到每个方法对应的所有订阅者集合,将订阅者从集合中移除。
2、移除订阅者中所有的订阅方法。
参考:
- greenrobot/EventBus(github.com)
- EventBus源码解析 - 掘金 (juejin.cn)