前言
分析Android源码确实挺累人的,看着看着就会丧失部分当初坚持要看下去的决心,但是又不能懈怠,所以源码的分心先缓一缓,不能产生一种对源码的厌恶感,这是很可怕的,所以为了保留仅剩的好奇心,选择了一个三方的框架来分析一下,换换脑子,这期间也有助于重新唤起分析Android源码的那份冲劲,学习道路上的绊脚石真的太多来,任何东西都可能对你使绊,所以我们在前进的过程中,要摸索出一套自己的方法论来克服这些困难,我目前的方法就是看腻来的只是可能先放一放,不要彻底丧失那份兴趣,可以换个知识点胡子和干点别的,这样可能会好点。所以才有这片文章。
EvenBus的使用就不介绍来,相信大家都知道如何使用,下面仅从实现原理和源码角度来分析一下,但是有几个注意事项需要注意一下。
- 几个注意事项
- 订阅方法的参数类型必须是引用类型
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(int value) {
System.out.println("value = [" + value + "]");
}
//int 是不行的,必须是他的包装类型:Integer
- 一个类可以有多个订阅的方法
- 有可能一个类中,订阅的方法参数一样,但是方法名字不一样
参数都是Integer,但是方法名字不一样
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(Integer value) {
System.out.println("value = [" + value + "]");
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent1(Integer value) {
System.out.println("value = [" + value + "]");
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent2(Integer value) {
System.out.println("value = [" + value + "]");
}
- 注册订阅方法的时候会根据注解中的priority属性对方法进行优先级的排序。
先分析一下EventBus对象的创建过程,EventBus是一个单例对象,由于他的初始化用到的参数比较多,所以使用类常用的Builder模式创建。
public class EventBus {
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder(){
this(DEFAULT_BUILDER);
};
//对后面用到的一些参数初始化。
EventBus(EventBusBuilder builder) {
subscriptionsByEventType = new HashMap<>();
typesBySubscriber = new HashMap<>();
stickyEvents = new ConcurrentHashMap<>();
mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
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;
}
}
public class EventBusBuilder {
private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
boolean logSubscriberExceptions = true;
boolean logNoSubscriberMessages = true;
boolean sendSubscriberExceptionEvent = true;
boolean sendNoSubscriberEvent = true;
boolean throwSubscriberException;
boolean eventInheritance = true;
boolean ignoreGeneratedIndex; //这个参数默认false,主要是用来区分是否使用类注解处理器获取订阅方法的,这里值分析通过反射获取。
boolean strictMethodVerification;
ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;
List<Class<?>> skipMethodVerificationForClasses;
List<SubscriberInfoIndex> subscriberInfoIndexes;
EventBusBuilder() {
}
}
注册的过程分两步进行
- 先找到要注册的方法
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
//根据注册类的Class对象获取要注册的方法。参见1.1
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
1.1 反射获取订阅的方法,这个步骤里面有一个缓存METHOD_CACHE,他的key是订阅类的Class对象,value是一个List,里面装的就是当前类所有被Subscribe注解的方法,因为反射是比较消耗性能的,没次都去反射获取调用的方法有损性能,所以找到所有的订阅方法后会做一个缓存,如果这个类之前已经注册过了,就直接返回已经注册的方法。
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
//通过上面知道ignoreGeneratedIndex = false
if (ignoreGeneratedIndex) {
参见1.2
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;
}
}
1.2
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
FindState findState = prepareFindState();参见1.3
//初始化FindState的一些成员变量,主要是把订阅类的class对象传进去了
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
//没有用注解的话,subscriberInfo == null,所以会走else分支
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 {
参见1.4
findUsingReflectionInSingleClass(findState);
}
//把class对象指向父类继续寻找订阅方法
findState.moveToSuperclass();
}
//释放FindState到缓存池里。
return getMethodsAndRelease(findState);
}
1.3 这里有一个FindState的缓存池,用来获取FindState对象,首次组册的时候FIND_STATE_POOL是空的,会new一个FindState,然后再使用完以后会把这个新的FindState放到FIND_STATE_POOL缓存池里面,方便后面复用。
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;
}
}
}
//缓存池为空,会创建一个,在使用完通过getMethodsAndRelease方法中会放到FIND_STATE_POOL中。
return new FindState();
}
static class FindState {
//里面装的是订阅的方法
final List<SubscriberMethod> subscriberMethods = new ArrayList<>();
//key是订阅方法的参数的class对象,value是方法或者方法的封装SubscriberMethod
final Map<Class, Object> anyMethodByEventType = new HashMap<>();
//key是订阅的方法签名,value是订阅类的class对象。
final Map<String, Class> subscriberClassByMethodKey = new HashMap<>();
final StringBuilder methodKeyBuilder = new StringBuilder(128);
1.4
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
//这个只会拿到当前类定义和重写的一些方法,并不会去把所有继承链上的方法拿出来。
//当低设备的手机上访问高版本的api的时候这个方法在可能会抛出异常,所以在catch中我们会获取所有的方法。
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;
//遍历找到Subscribe注解的方法。循环结束以后就会找到所有订阅的方法方法
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];
参见1.4
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");
}
}
}
1.5
boolean checkAdd(Method method, Class<?> eventType) {
//检查eventType类型参数的订阅方法是否已经存在
Object existing = anyMethodByEventType.put(eventType, method);
if (existing == null) {
return true;//不存在返回true,会添加到subscriberMethods的map里面
} else {
// 已经有evetType参数类型的方法,经过下面if的逻辑处理,
//会把这个方法封装成SubscriberMethodFinder类型,
//如果evetType参数类型的方法有多个,因为第一次已经改变的existing
//的类型,所以直接跳过if的逻辑
//existing的变化
//第一次existing ->Method, 第二次,第一次existing -> SubscriberMethodFinder
if (existing instanceof Method) {
//如果存在,再根据方法签名检查订阅的类是不是存在。参见1.6
if (!checkAddWithMethodSignature((Method) existing, eventType)) {
throw new IllegalStateException();
}
//把已经存在的方法重新打包封装成SubscriberMethodFinder存进来,下次如果有参数类型一样的方法,就会跳过这部分逻辑,直接通过签名验证以后添加
anyMethodByEventType.put(eventType, this);
}
return checkAddWithMethodSignature(method, eventType);
}
}
1.6 这里涉及到类的方法签名,在Java中唯一确定一个方法的依据是方法的名字和方法的参数,返回值是不参与方法签名的
private boolean checkAddWithMethodSignature(Method method, Class<?> eventType) {
methodKeyBuilder.setLength(0);
//拼接方法名字和参数的名字
methodKeyBuilder.append(method.getName());
methodKeyBuilder.append('>').append(eventType.getName());
//methodKey可以唯一代表一个类中的某个方法,
String methodKey = methodKeyBuilder.toString();
Class<?> methodClass = method.getDeclaringClass();
Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass);
//methodClassOld永远是false,因为一个类中不可能出先方法签名一样的方法,
if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) {
// Only add if not already found in a sub class
return true;
} else {
// Revert the put, old class is further down the class hierarchy
subscriberClassByMethodKey.put(methodKey, methodClassOld);
return false;
}
}
-
找到要注册的方法后才去真真的执行订阅操作
2.1 注册其实就是一个subscribe方法,只不过是在循环中重复调用组册的,post事件的时候其实是从subscriptionsByEventTyp的map里拿的订阅方法。
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
//获取订阅方法的参数类型
Class<?> eventType = subscriberMethod.eventType;
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
//获取参数类型所对应的参数方法,注意事项中已经说过。
//同一个参数类型,可能有多个订阅的方法,虽然实际情况很少这样使用。
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
//没找到创建并添加进subscriptionsByEventType
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);
}
}
//这里是对形同参数类型的方法根据priority进行排序。
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;
}
}
//根据订阅类找到这个类中的订阅的方法,下面的逻辑主要是为判断某个类是否已经注册过或者对外提供一些api。
//eg:isRegistered(Object subscriber),unregister(Object subscriber)...
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.getDefault().post(66666);//分发一个Integer类型的事件。
public void post(Object event) {
//获取当前线程的事件队列。ThreadLocal可以是每个线程拥有自己的事件队列
PostingThreadState postingState = currentPostingThreadState.get();
List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);
if (!postingState.isPosting) {
//判断当前分发事件的线程是否是主线程
postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();
postingState.isPosting = true;
if (postingState.canceled) {
throw new EventBusException("Internal error. Abort state was not reset");
}
try {
//循环分发事件
while (!eventQueue.isEmpty()) {
//参见3.1
postSingleEvent(eventQueue.remove(0), postingState);
}
} finally {
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
3.1 postSingleEvent分发有两个步骤
- 找到分发事件的继承链上的所有class对象
- 遍历第一步的中找到的所有class集合,找到该class的所有已订阅的分发
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
Class<?> eventClass = event.getClass();
boolean subscriptionFound = false;
if (eventInheritance) {
//找到eventClass的简介或者直接的夫类class对象和所实现的接口class对象
//会一直找到Object为止。
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);参见3.2
}
} else {
subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
}
if (!subscriptionFound) {
if (logNoSubscriberMessages) {
Log.d(TAG, "No subscribers registered for event " + eventClass);
}
if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
eventClass != SubscriberExceptionEvent.class) {
post(new NoSubscriberEvent(this, event));
}
}
}
3.2 更具发送事件的Class找到该Class的所有订阅的分发
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
CopyOnWriteArrayList<Subscription> subscriptions;
synchronized (this) {
//根据class从订阅的Map中找订阅的分发
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
//找到后遍历调用订阅的分发
for (Subscription subscription : subscriptions) {
postingState.event = event;
postingState.subscription = subscription;
boolean aborted = false;
try {
//参见3.3
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;
}
3.3根据订阅分发期望的线程和分发事件的线程发送事件
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 {
//非主线程分发的,参见3.4
mainThreadPoster.enqueue(subscription, event);
}
break;
case BACKGROUND:
if (isMainThread) {
//参见3.5
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);
}
}
3.3.1结社我们来分析一下PendingPost这个类
final class PendingPost {
//缓存池,最大数量是10000个
private final static List<PendingPost> pendingPostPool = new ArrayList<PendingPost>();
Object event;//消息
Subscription subscription; //订阅分方法和订阅类的封装
PendingPost next;//用来实现的队列的。
private PendingPost(Object event, Subscription subscription) {
this.event = event;
this.subscription = subscription;
}
//类似于Android中的Messager#obtain方法,缓存中有就直接那,没有用完后放到缓存中
static PendingPost obtainPendingPost(Subscription subscription, Object event) {
synchronized (pendingPostPool) {
int size = pendingPostPool.size();
if (size > 0) {
PendingPost pendingPost = pendingPostPool.remove(size - 1);
pendingPost.event = event;
pendingPost.subscription = subscription;
pendingPost.next = null;
return pendingPost;
}
}
return new PendingPost(event, subscription);
}
//1.释放资源
//2. 放入缓存中
static void releasePendingPost(PendingPost pendingPost) {
pendingPost.event = null;
pendingPost.subscription = null;
pendingPost.next = null;
synchronized (pendingPostPool) {
// Don't let the pool grow indefinitely
if (pendingPostPool.size() < 10000) {
pendingPostPool.add(pendingPost);
}
}
}
}
3.3.2PendingPostQueue是一个简单的实现,用的是链表的实方式。
final class PendingPostQueue {
private PendingPost head;//队列的头
private PendingPost tail;//链表的尾
synchronized void enqueue(PendingPost pendingPost) {
if (pendingPost == null) {
throw new NullPointerException("null cannot be enqueued");
}
if (tail != null) {//tail已经存在了,把pendingPost放到队尾。
tail.next = pendingPost;
tail = pendingPost;
} else if (head == null) {//队列空的时候创建队列的头和尾
head = tail = pendingPost;
} else {
throw new IllegalStateException("Head present, but no tail");
}
notifyAll();
}
//出队操作。
synchronized PendingPost poll() {
PendingPost pendingPost = head;
if (head != null) {
head = head.next;
if (head == null) {
tail = null;
}
}
return pendingPost;
}
synchronized PendingPost poll(int maxMillisToWait) throws InterruptedException {
if (head == null) {
wait(maxMillisToWait);
}
return poll();
}
}
3.4内部通过Handler和消息队列类处理的,
void enqueue(Subscription subscription, Object event) {
//从PendingPost的缓存中拿到一个将要发送到主线的pendingPost,这个缓存的最大数据量是10000个。
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
//放到消息队列中
queue.enqueue(pendingPost);
if (!handlerActive) {
handlerActive = true;
发送Messager处理队列中的消息
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
}
}
}
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;
//不过这里需要注意的是EventBus为HandlerPoster处理调用注册
//设定了时间上限,
//也就是构造器中初始化的maxMillisInsideHandleMessage,
//在EventBus中初始化mainThreadPost时为其指定了10ms,
//也就是while循环超过10ms之后会退出handleMessage方法,
//并将handleActive置位true,并再次发送消息,
//使得该handler再次调用handleMessage()方法,继续处理队列中的//注册信息,这是为了避免队列过长是,
//while循环阻塞主线程造成卡顿。
if (timeInMethod >= maxMillisInsideHandleMessage) {
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
rescheduled = true;
return;
}
}
} finally {
handlerActive = rescheduled;
}
}
3.5订阅分发在子线程中分发
3.5.1 先看一下BackgroundPoster,是一个runable对象,用来在子线程中调用方法
final class BackgroundPoster implements Runnable {
private final PendingPostQueue queue;
private final EventBus eventBus;
private volatile boolean executorRunning;
BackgroundPoster(EventBus eventBus) {
this.eventBus = eventBus;
queue = new PendingPostQueue();
}
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);
}
}
}
@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) {
Log.w("Event", Thread.currentThread().getName() + " was interruppted", e);
}
} finally {
executorRunning = false;
}
}
}
class AsyncPoster implements Runnable {
private final PendingPostQueue queue;
private final EventBus eventBus;
AsyncPoster(EventBus eventBus) {
this.eventBus = eventBus;
queue = new PendingPostQueue();
}
public void enqueue(Subscription subscription, Object event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
queue.enqueue(pendingPost);//没次都会创建一个线程来运行订阅的分发。
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);
}
}
BackgroundPoster类,虽然也实现了Runnable接口,虽然也在子线程中执行EventBus的反射回调方法。但是与AsyncPoster类不同的是:
- AsyncPoster类每次任务都会新建一个线程,并发执行队列中的任务
- 而BackgroundPoster类只会新建一个子线程,队列中的任务,只会顺序执行。
到这里就分析完来。