1.EventBus是一个单例
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
2.构造方法
实例化一个集合放置订阅方法,事件类型等…
实例化Poster,处理不同线程的问题,具体在第五步
1)mainThreadPoster
public class HandlerPoster extends Handler implements Poster{}
如何生成HandlerPoster代码省略
以上,mainThreadPoster是一个Handler类继承了Poster接口,
其中Handler持有的Looper是主线程Looper,
所以mainThreadPoster的handleMessage()方法会在主线程执行
2)backgroundPoster
final class BackgroundPoster implements Runnable, Poster {}
3)asyncPoster
class AsyncPoster implements Runnable, Poster {}
以上继承Runnable接口,
所以(2)+(3)poster会在工作线程执行
3.register
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
//通过反射找到注册类所有含有@Subscribe注解的公共方法
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
//注册类订阅
subscribe(subscriber, subscriberMethod);
}
}
}
通过反射找到注册类所有含有@Subscribe注解的公共方法
并调用subscribe()
4.subscribe(注册调用的方法)
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
//1.实例化subscriptionsByEventType:Map<事件对象,订阅方法>,就是将带有@Subscribe注解的公共方法按优先级顺序放进这个Map中
// 每个订阅方法都是subscriptionsByEventType中的一项
//2.实例化typesBySubscriber:Map<注册类(activity,fragemnt),List<EventType>>,每个订阅方法都有一个参数就是EventType,
// 把所有EventType放进一个叫做subscribedEvents:List<Class<?>>的list,在和类组成typesBySubscriber。
// 每个注册类以及注册类中的事件类型列表就是typesBySubscriber中的一项
//3.粘性事件注册时直接回调订阅方法
}
生成post事件时需要遍历的订阅方法列表
5.post
post方法会携带EventType类型,通过EventType类型遍历注册时生成的subscriptionsByEventType列表
subscriptions = subscriptionsByEventType.get(eventClass);
for (Subscription subscription : subscriptions) {
postToSubscription(subscription, event, postingState.isMainThread);
}
根据EventType类型取到对应的注册订阅方法列表,再根据订阅方法的线程模式分情况执行
1)POSTING:同一个线程执行 不需要处理
2)MAIN:主线程执行,需要判断post所在的线程是不是主线程,是就直接执行,不是通过mainThreadPoster(Handler)执行
3)BACKGROUND:后台线程判断post所在线程是不是主线程,是就用backgroundPoster(Runnable)执行,不是就直接执行
4)ASYNC:异步线程 不管是不是主线程都利用asyncPoster(Runnable)执行
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);
}
}
6.Note
Note1:是否主线程判断
根据Looper.prepare()==Looper.getMainLooper()判断
Looper.prepare():获取所在线程的Looper
Looper.getMainLooper():获取主线程Looper
Note2:后台和异步的区别
后台线程单个执行(BackgroundPoster是加锁synchronized的),异步来一个执行一个
后台线程enqueue() public void enqueue(Subscription subscription, Object
event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
queue.enqueue(pendingPost);
if (!executorRunning) {
executorRunning = true;
eventBus.getExecutorService().execute(this);
}
}
}异步线程enqueue() public void enqueue(Subscription subscription, Object
event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
queue.enqueue(pendingPost);
eventBus.getExecutorService().execute(this);
}
Note3:invokeSubscriber()
subscription.subscriberMethod.method.invoke(subscription.subscriber,
event); 利用反射直接调用订阅方法