目录
一、EventBus解决了什么问题
二、如何使用EventBus
三、EventBus如何注册
四、EventBus注册总结
五、EventBus如何分发事件
六、EventBus如何处理事件
七、EventBus如何处理事件总结
八、EventBus如何解除注册
一、EventBus解决了什么问题
EventBus最主要的功能是通过观察者模式,实现了事件的分发,并自动切换执行的线程。观察者需要使用@Subscribe注册事件分发后需要执行的方法和所要执行的线程。被观察者只需要执行EventBus.getDefault().post(EventPost("from event Test"))发送一个对象即可实现事件分发,
二、如何使用EventBus
1、在需要观察者的页面注册EventBus
EventBus.getDefault().register(this)
2、使用注解标记当事件发生时需要调用的方法
@Subscribe
fun onEventPost(event: EventPost){
tv_main_content.text = event.content
}
3、页面销毁时需要解注册EventBus
EventBus.getDefault().unregister(this)
三、EventBus如何注册
1 首先需要调用EventBus.getDefault().register(this)
EventBus.java
/**
* Registers the given subscriber to receive events. Subscribers must call {@link #unregister(Object)} once they
* are no longer interested in receiving events.
* <p/>
* Subscribers have event handling methods that must be annotated by {@link Subscribe}.
* The {@link Subscribe} annotation also allows configuration like {@link
* ThreadMode} and priority.
*/
//subscriber为观察者对象
public void register(Object subscriber) {
//subscriber取出观察者对象的class
Class<?> subscriberClass = subscriber.getClass();
//找到发送事件后需要调用的方法
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
//订阅方法和订阅对象关联
synchronized (this) {
//遍历订阅方法
for (SubscriberMethod subscriberMethod : subscriberMethods) {
//订阅
subscribe(subscriber, subscriberMethod);
}
}
}
2 如何找到事件发送后需要调用的方法subscriberMethodFinder.findSubscriberMethods(subscriberClass);
SubscriberMethodFinder.java
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
//METHOD_CACHE使用ConcurrentHashMap来保证线程同步,如果缓存中解析了订阅的方法那么直接返回(这里是因为反射取方法很耗时)
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
//
if (ignoreGeneratedIndex) {
//通过反射查找订阅方法
subscriberMethods = findUsingReflection(subscriberClass);
} else {
//通过SubscriberInfo获取订阅方法
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;
}
}
2.1.1 通过反射查找订阅方法findUsingReflection(subscriberClass);
SubscriberMethodFinder.java
private List<SubscriberMethod> findUsingReflection(Class<?> subscriberClass) {
//准备查找的类
FindState findState = prepareFindState();
//使用订阅类class初始化查找状态类
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
//开始循环反射处理订阅类
findUsingReflectionInSingleClass(findState);
//查找类开始查找,订阅类的父类
findState.moveToSuperclass();
}
return getMethodsAndRelease(findState);
}
2.1.2 prepareFindState();准备查找状态的类
SubscriberMethodFinder.java
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();
}
2.1.3 findUsingReflectionInSingleClass(findState);从查找类中反射取出订阅方法
SubscriberMethodFinder.java
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...···
}
//遍历订阅类中的方法
for (Method method : methods) {
//得到方法修饰符
int modifiers = method.getModifiers();
//方法必须为public
// private static final int MODIFIERS_IGNORE = Modifier.ABSTRACT | Modifier.STATIC | BRIDGE | SYNTHETIC;
// 忽视抽象方法,静态方法,桥接方法,合成方法
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
//取出参数
Class<?>[] parameterTypes = method.getParameterTypes();
//参数为1个
if (parameterTypes.length == 1) {
//取出以Subscribe注解标记的方法
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
//注解不为空
if (subscribeAnnotation != null) {
//获取参数的class类型
Class<?> eventType = parameterTypes[0];
//添加到FindState中
if (findState.checkAdd(method, eventType)) {
//取出订阅方法的线程模型
ThreadMode threadMode = subscribeAnnotation.threadMode();
//存储订阅方法到findState的subscriberMethods,保存优先级,是否为粘性事件
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
}
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
···}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
···}
}
}
2.1.4 返回到 findUsingReflection(subscriberClass); 最后返回 getMethodsAndRelease(findState);
SubscriberMethodFinder.java
private List<SubscriberMethod> getMethodsAndRelease(FindState findState) {
//创建订阅方法的List
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;
}
2.2.1 通过SubscriberInfo获取订阅方法 findUsingInfo(subscriberClass);
SubscriberMethodFinder.java
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
//准备查找类FindState
FindState findState = prepareFindState();
//初始化
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
//获取SubscriberInfo
findState.subscriberInfo = getSubscriberInfo(findState);
if (findState.subscriberInfo != null) {
//获取订阅方法
SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
for (SubscriberMethod subscriberMethod : array) {
//添加到findstate
if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
findState.subscriberMethods.add(subscriberMethod);
}
}
} else {
//如果没有注解处理器处理那么降级为使用反射出处理
findUsingReflectionInSingleClass(findState);
}
//移动到父类
findState.moveToSuperclass();
}
//释放findstate
return getMethodsAndRelease(findState);
}
2.2.2 获取SubscriberInfo getSubscriberInfo(findState);
SubscriberMethodFinder.java
private SubscriberInfo getSubscriberInfo(FindState findState) {
//如果findstate中存在subscriberInfo那么直接取出来
if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
if (findState.clazz == superclassInfo.getSubscriberClass()) {
return superclassInfo;
}
}
//subscriberInfoIndexes 不为空那么冲subscriberInfoIndexes取subscriberInfo
if (subscriberInfoIndexes != null) {
for (SubscriberInfoIndex index : subscriberInfoIndexes) {
SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
if (info != null) {
return info;
}
}
}
return null;
}
2.2.3 如何获取SubscriberInfo,SubscriberInfo是通过注解处理器EventBusAnnotationProcessor生成的,这样做是为了在编译时期就取到订阅方法的信息,在运行时取订阅方法的信息会有性能上的损耗
2.2.4 如何使用注解解析订阅方法
① 添加注解解析
apply plugin: 'kotlin-kapt'
kapt {
arguments {
arg('eventBusIndex', 'com.yangdainsheng.event.MyEventBusIndex')
}
}
kapt this.rootProject.depsLibs["eventbus-annotation-processor"]
② build项目生成com.yangdainsheng.event.MyEventBusIndex这个类
③ 在Application中添加添加生成的类EventBus.builder().addIndex(MyEventBusIndex()).build()
2.2.5 源码解析,EventBus.builder().addIndex(MyEventBusIndex())
/** Adds an index generated by EventBus' annotation preprocessor. */
public EventBusBuilder addIndex(SubscriberInfoIndex index) {
if (subscriberInfoIndexes == null) {
subscriberInfoIndexes = new ArrayList<>();
}
subscriberInfoIndexes.add(index);
return this;
}
生成类MyEventBusIndex继承自SubscriberInfoIndex,将生成类添加到subscriberInfoIndexes,我们在取SubscribeInfo的时候会调用
private SubscriberInfo getSubscriberInfo(FindState findState) {
····
if (subscriberInfoIndexes != null) {
for (SubscriberInfoIndex index : subscriberInfoIndexes) {
SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
if (info != null) {
return info;
}
}
}
return null;
}
也就是会调用生成代码的index.getSubscriberInfo(findState.clazz);,生成类代码
MyEventBusIndex.java
/** 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(com.yangdainsheng.wan.MainActivity.class, true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onEventPost", EventPost.class),
}));
}
private static void putIndex(SubscriberInfo info) {
SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);
}
//这里会在取SubscriberInfo的时候调用
@Override
public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {
SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);
if (info != null) {
return info;
} else {
return null;
}
}
}
这样就把订阅信息加载到EventBus中,在返回到方法findUsingInfo(subscriberClass);
3 所有订阅方法都取完了,返回到register(Object subscriber)的开始关联订阅方法和订阅对象
synchronized (this) {
//遍历订阅方法
for (SubscriberMethod subscriberMethod : subscriberMethods) {
//订阅
subscribe(subscriber, subscriberMethod);
}
}
3.1 subscribe(subscriber, subscriberMethod);
EventBus
// Must be called in synchronized block
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) {
//如果不存在,那么创建一个线程安全的List
subscriptions = new CopyOnWriteArrayList<>();
//按事件类型存储订阅描述
subscriptionsByEventType.put(eventType, subscriptions);
} else {
····
}
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);
}
}
}
四 EventBus注册总结
1 先注册调用EventBus.getDefault().register(this)。 如果配置了注解处理器,那么会自动生成SubscriberInfoIndex,在Application中添加EventBus.builder().addIndex(MyEventBusIndex()).build(),将自动生成的类添加到EventBus中。
2 使用注解@subscribe可设置ThreadMode,优先级,是否是粘性事件
3 取出订阅方法,如果配置注解处理器直接从SubscriberInfo中取,如若没有那么从反射中获取
4 将订阅方法和订阅对象关联起来,
五 EventBus如何分发事件
5.1 EventBus.getDefault().post(EventPost("from event Test")) 用来发送事件
EventBus.java
/** Posts the given event to the event bus. */
public void post(Object event) {
//从ThreadLocal中取出PostingThreadState,这里存储了事件的队列,是否在发送中,是都在主线程,发送事件的描述
PostingThreadState postingState = currentPostingThreadState.get();
//取出之前还没有发送的事件
List<Object> eventQueue = postingState.eventQueue;
//将发送事件添加到事件队列中
eventQueue.add(event);
//不是发送状态
if (!postingState.isPosting) {
//为PostingThreadState赋值。是否是主线程
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;
}
}
}
5.2 postSingleEvent(eventQueue.remove(0), postingState); 用于处理事件的发送
EventBus.java
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
//取出事件的class
Class<?> eventClass = event.getClass();
boolean subscriptionFound = false;
/是否需要考虑继承关系
if (eventInheritance) {
//取出继承的所有事件
List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);
int countTypes = eventTypes.size();
for (int h = 0; h < countTypes; h++) {
Class<?> clazz = eventTypes.get(h);
//处理要发送消息
subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
}
} else {
//处理要发送消息
subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
}
···
}
5.3 postSingleEventForEventType(event, postingState, clazz); 根据事件类型提取出订阅事件来处理
EventBus.java
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;
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;
}
六 EventBus如何处理事件
6.1 处理事件是从 postToSubscription(subscription, event, postingState.isMainThread);开始的
EventBus.java
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
//首先取出订阅事件的ThreadMode,分一下几种
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);
}
}
6.2 POSTING 默认的就这这种方法,直接在当前线程调用invokeSubscriber(subscription, event);
EventBus.java
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);
}
}
6.3 MAIN 如果当前线程是主线程直接调用反射方法执行,否则放入主线程队列mainThreadPoster.enqueue(subscription, event);
mainThreadPoster是Poster类型,通过mainThreadSupport.createPoster(this)创建
MainThreadSupport.java
/**
* Interface to the "main" thread, which can be whatever you like. Typically on Android, Android's main thread is used.
*/
public interface MainThreadSupport {
boolean isMainThread();
Poster createPoster(EventBus eventBus);
class AndroidHandlerMainThreadSupport implements MainThreadSupport {
private final Looper looper;
public AndroidHandlerMainThreadSupport(Looper looper) {
this.looper = looper;
}
@Override
public boolean isMainThread() {
return looper == Looper.myLooper();
}
@Override
public Poster createPoster(EventBus eventBus) {
//这里创建了主线程的HandlerPoster
return new HandlerPoster(eventBus, looper, 10);
}
}
}
HandlerPoster.java
//这个就是主线程队列,mainThreadPoster.enqueue(subscription, event); 就是调用的这个方法
public void enqueue(Subscription subscription, Object event) {
//首先从PendingPost池中取出 PendingPost对象
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
//将PendingPost放入到队列中
queue.enqueue(pendingPost);
//handle不是活动状态,需要发送一个空消息给主线程队列,让HandlerPoster handleMessage调用起来
if (!handlerActive) {
handlerActive = true;
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
}
}
}
PendingPostQueue使用链表实现的队列
PendingPostQueue.java
synchronized void enqueue(PendingPost pendingPost) {
if (pendingPost == null) {
throw new NullPointerException("null cannot be enqueued");
}
//向尾部插入一个事件
if (tail != null) {
tail.next = pendingPost;
tail = pendingPost;
} else if (head == null) {
head = tail = pendingPost;
} else {
throw new IllegalStateException("Head present, but no tail");
}
//唤醒所有线程
notifyAll();
}
事件是如何在主线程被处理的。mainThreadPoster.enqueue(subscription, event);添加事件的时候,如果主线程队列不是活动状态那么会发送一个空消息去触发这个handleMessage(),如果PendingPostQueue一直有事件会一直处理到空为止
HandlerPoster.java
@Override
public void handleMessage(Message msg) {
boolean rescheduled = false;
try {
long started = SystemClock.uptimeMillis();
//开启循环处理任务
while (true) {
//取出一个任务
PendingPost pendingPost = queue.poll();
if (pendingPost == null) {
synchronized (this) {
// Check again, this time in synchronized
pendingPost = queue.poll();
if (pendingPost == null) {
handlerActive = false;
return;
}
}
}
//处理事件
eventBus.invokeSubscriber(pendingPost);
long timeInMethod = SystemClock.uptimeMillis() - started;
if (timeInMethod >= maxMillisInsideHandleMessage) {
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
rescheduled = true;
return;
}
}
} finally {
handlerActive = rescheduled;
}
}
eventBus.invokeSubscriber(pendingPost);开始主线程处理事件
EventBus.java
/**
* Invokes the subscriber if the subscriptions is still active. Skipping subscriptions prevents race conditions
* between {@link #unregister(Object)} and event delivery. Otherwise the event might be delivered after the
* subscriber unregistered. This is particularly important for main thread delivery and registrations bound to the
* live cycle of an Activity or Fragment.
*/
void invokeSubscriber(PendingPost pendingPost) {
Object event = pendingPost.event;
Subscription subscription = pendingPost.subscription;
//处理PendingPost的状态
PendingPost.releasePendingPost(pendingPost);
if (subscription.active) {
//反射调用方法
invokeSubscriber(subscription, event);
}
}
6.4 MAIN_ORDERED 直接丢到主线程队列中执行
6.5 BACKGROUND 如果在发送线程在主线程,丢到子线程执行。否则直接反射执行
EventBus.java
case BACKGROUND:
if (isMainThread) {
backgroundPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
backgroundPoster.enqueue(subscription, event);中的backgroundPoster类型为BackgroundPoster
BackgroundPoster.java
public void enqueue(Subscription subscription, Object event) {
//创建一个事件PendingPost
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
//添加到执行队列中
queue.enqueue(pendingPost);
//如果线程池未执行那么开始执行
if (!executorRunning) {
executorRunning = true;
//这个线程池可以自定义
eventBus.getExecutorService().execute(this);
}
}
}
EventBusBuilder.java
//这个是默认的线程池,无核心线程,最大线程数无限,
private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
eventBus.getExecutorService().execute(this);执行的就是在下面的run()方法
BackgroundPoster.java
@Override
public void run() {
try {
try {
//循环处理消息
while (true) {
//防止多线程竞争锁
PendingPost pendingPost = queue.poll(1000);
if (pendingPost == null) {
synchronized (this) {
// Check again, this time in synchronized
pendingPost = queue.poll();
if (pendingPost == null) {
executorRunning = false;
return;
}
}
}
//开始执行
eventBus.invokeSubscriber(pendingPost);
}
} catch (InterruptedException e) {
eventBus.getLogger().log(Level.WARNING, Thread.currentThread().getName() + " was interruppted", e);
}
} finally {
executorRunning = false;
}
}
6.6 ASYNC 直接添加到子线程执行asyncPoster.enqueue(subscription, event); asyncPoster也是Poster
AsyncPoster.java
public void enqueue(Subscription subscription, Object event) {
//创建消息
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
//添加到队列
queue.enqueue(pendingPost);
//开始执行,这里使用的线程池和BackgroundPoster使用的线程池是一个
eventBus.getExecutorService().execute(this);
}
@Override
public void run() {
//从消息队列中取出
PendingPost pendingPost = queue.poll();
if(pendingPost == null) {
throw new IllegalStateException("No pending post available");
}
//反射执行
eventBus.invokeSubscriber(pendingPost);
}
七 EventBus如何处理事件总结
订阅事件可自定义ThreadMode
1 POSTING 当前线程直接调用订阅方法反射执行
2 MAIN 如果当前线程是主线程直接调用反射方法执行,否则放入主线程队列
3 MAIN_ORDERED 直接丢到主线程队列中执行
4 BACKGROUND 如果在发送线程在主线程,丢到子线程执行。否则直接反射执行
5 ASYNC 直接添加到子线程执行
八 EventBus如何解除注册
EventBus.getDefault().unregister(this)
EventBus.java
/** 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());
}
}
EventBus.java
/** Only updates subscriptionsByEventType, not typesBySubscriber! Caller must update typesBySubscriber. */
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--;
}
}
}
}