EventBus,由greenrobot组织贡献(该组织还贡献了greenDAO),一个Android事件发布/订阅轻量级框架;
进程内EventBus可以代替Android传统的Intent,Handler,Broadcast或接口函数,在Fragment,Activity,Service线程之间传递数据,执行方法;
github地址 https://github.com/greenrobot/EventBus 点击打开链接
在没有它之前,进程内通信一直都是用的广播来发送接收消息,后来用了后发现真的是太方便了,而且还是轻量级的,最近研究了下它的源码,
学习了下大神牛逼的架构和思维,确实很厉害,为啥我没想到呢。
怎么使用的就不做介绍了,相信大家都会用,下面直接进入正文
先看下源码结构,如图:
代码量其实不是很多,很多类里面就只有一点代码,前面3个文件目录都是一些辅助工具类,不是核心,有空可以去学习下,
这里只解析主干逻辑。
平时我们主要用这几个方法:注册订阅者,注销订阅者,定义订阅方法,post事件,所以就从这几个方面开始解析
首先我们知道EventBus用的是单例模式,整个进程中只会有一个EventBus的实例
static volatile EventBus defaultInstance;
/** Convenience singleton for apps using a process-wide EventBus instance. */
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
接下来看下定义订阅方法
@Subscribe(threadMode = ThreadMode.MAIN)
public void refreshUI(RefreshBagEvent event) {
}
@Subscribe
public void loadData(DataChangeEvent event) {
}
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
/**
* 指定订阅方法所在线程
* @return
*/
ThreadMode threadMode() default ThreadMode.POSTING;
/**
* 是否开启粘性事件
* If true, delivers the most recent sticky event (posted with
* {@link EventBus#postSticky(Object)}) to this subscriber (if event available).
*/
boolean sticky() default false;
/**
* 优先级
* Subscriber priority to influence the order of event delivery.
* Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before
* others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of
* delivery among subscribers with different {@link ThreadMode}s! */
int priority() default 0;
}
为啥要定义这么一个注解呢?
问题先放这,后面揭晓,接下来看下注册订阅者方法register()
/**
* Registers the given subscriber to receive events. Subscribers must call {@link #unregister(Object)} once they
* are no longer interested in receiving events.
*
* Subscribers have event handling methods that must be annotated by {@link Subscribe}.
* The {@link Subscribe} annotation also allows configuration like {@link
* ThreadMode} and priority.
*/
public void register(Object subscriber) {
Class> subscriberClass = subscriber.getClass();
// 获取订阅者订阅的方法
List subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
// 加上同步block,可能同时有多处都在注册
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
private static final Map, List> METHOD_CACHE = new ConcurrentHashMap<>();
List findSubscriberMethods(Class> subscriberClass) {
List 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;
}
}
private List findUsingInfo(Class> subscriberClass) {
FindState findState = prepareFindState();
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
findState.subscriberInfo = getSubscriberInfo(findState);
// 这里应该是从缓存中获取订阅的方法,不过看源码findState.subscriberInfo永远都是null,所以进不去
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 {
// 利用反射获取订阅方法储存在findState里面
findUsingReflectionInSingleClass(findState);
}
findState.moveToSuperclass();
}
// 从findState中获取订阅方法
return getMethodsAndRelease(findState);
}
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();
// 过滤掉非public、静态的方法
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
// 获取方法中参数
Class>[] parameterTypes = method.getParameterTypes();
// 如果只有一个参数
if (parameterTypes.length == 1) {
// 获取方法中Subscribe注解
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
// 方法中Subscribe注解不为null
if (subscribeAnnotation != null) {
Class> eventType = parameterTypes[0];
// 检查findState是否添加过这个订阅方法
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)) {
// 抛出异常,订阅的方法必须是public,不带static、abstract的
String methodName = method.getDeclaringClass().getName() + "." + method.getName();
throw new EventBusException(methodName +
" is a illegal @Subscribe method: must be public, non-static, and non-abstract");
}
}
}
private List getMethodsAndRelease(FindState findState) {
List 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;
}
到这里,这个订阅者的方法都以List的形式返回了,接着回到register()
public void register(Object subscriber) {
Class> subscriberClass = subscriber.getClass();
// 获取订阅者订阅的方法
List subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
// 加上同步block,可能同时有多处都在注册
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
// Must be called in synchronized block
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
// 获取事件.class对象
Class> eventType = subscriberMethod.eventType;
// 创建一个含有订阅者和订阅方法的订阅实体
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
// 根据事件类型获取订阅实体集合,CopyOnWriteArrayList是线程安全的
CopyOnWriteArrayList subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions == null) {
// 如果subscriptionsByEventType还没有事件.class对象eventType相关的订阅实体集合,就new 一个
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
} else {
// 如果subscriptionsByEventType有eventType相关的订阅实体集合,且包含newSubscription,抛出异常已经注册过了
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
// 把newSubscription添加到subscriptions集合中,默认优先级的情况下添加到末尾;优先级越大添加越靠前
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;
}
}
// typesBySubscriber用于判断是否注册过某个订阅者
List> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
subscribedEvents.add(eventType);
// sticky默认false
if (subscriberMethod.sticky) {
// eventInheritance 默认为true
// 如果eventType代表的类或者接口是candidateEventType代表的类或者接口或者父类父接口,也要post事件
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).
Set, Object>> entries = stickyEvents.entrySet();
for (Map.Entry, 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);
}
}
}
/**
* 储存事件及父类父接口Class对象;
* key:事件Class对象,value:事件及父类父接口Class对象
*/
private static final Map, List>> eventTypesCache = new HashMap<>();
/**
* 储存事件及对应方法;
* key是事件的Class对象,value是订阅者及订阅的方法集合
*/
private final Map, CopyOnWriteArrayList> subscriptionsByEventType;
/**
* 储存订阅者及事件Class对象;
* 用于判断订阅者是否注册过
*/
private final Map
把事件和订阅者相关的方法存储在subscriptionsByEventType 里面,因为一个事件可能在很多地方都注册过,最后还有一个粘性事件
sticky的处理,什么是粘性事件,比如这个事件在A页面发送完毕了,一般情况下注册过的地方就会马上接受到这个事件处理掉,
然后打开过注册了这个事件的B页面的时候,是不会再接受到这个事件的,而粘性事件就相反,打开B页面同样会接受到这个事件,
可以看下源码
// sticky默认false
if (subscriberMethod.sticky) {
// eventInheritance 默认为true
// 如果eventType代表的类或者接口是candidateEventType代表的类或者接口或者父类父接口,也要post事件
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).
Set, Object>> entries = stickyEvents.entrySet();
for (Map.Entry, 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);
}
}
private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
if (stickyEvent != null) {
// If the subscriber is trying to abort the event, it will fail (event is not tracked in posting state)
// --> Strange corner case, which we don't take care of here.
postToSubscription(newSubscription, stickyEvent, isMainThread());
}
}
注册事件其实就是用一个HashMap subscriptionsByEventType 把事件和注册了事件相关的类和方法储存起来,方便后面post(事件)使用。
接下来看下post()方法,
private final ThreadLocal currentPostingThreadState = new ThreadLocal() {
@Override
protected PostingThreadState initialValue() {
// 初始化一个PostingThreadState对象
return new PostingThreadState();
}
};
/** Posts the given event to the event bus. */
public void post(Object event) {
PostingThreadState postingState = currentPostingThreadState.get();
List
http://blog.csdn.net/msn465780/article/details/78673656 点击打开链接
/** For ThreadLocal, much faster to set (and get multiple values). */
final static class PostingThreadState {
final List
一开始是存储post的事件,因为可能有很多地方都在post,接下来循环调用postSingleEvent(),
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
Class> eventClass = event.getClass();
boolean subscriptionFound = false;
// eventInheritance默认为true
if (eventInheritance) {
List> 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);
}
if (!subscriptionFound) {
if (logNoSubscriberMessages) {
// post事件,但是没有地方注册就打印出提示日志
logger.log(Level.FINE, "No subscribers registered for event " + eventClass);
}
if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
eventClass != SubscriberExceptionEvent.class) {
// 不知道为啥还要执行以下代码,既然没有注册这个事件还去post一个未被注册的新事件,不是形成了递归吗?
post(new NoSubscriberEvent(this, event));
}
}
}
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class> eventClass) {
CopyOnWriteArrayList subscriptions;
synchronized (this) {
// 从储存regist的方法中获取事件对应的方法
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
// 开始循环把同一个事件post到注册者,意思就是调用这个事件订阅的方法
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;
}
postToSubscription(),这个方法还熟悉吗?前面粘性事件Sticky中提到过,就是用的它,是它是它就是它!
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
switch (subscription.subscriberMethod.threadMode) {
case POSTING:
invokeSubscriber(subscription, event);
break;
case MAIN:
if (isMainThread) {
// 如果post()在主线程,则立即反射调用订阅方法
invokeSubscriber(subscription, event);
} else {
// 否认,加入UI线程消息队列末尾
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) {
// 如果post()的线程为UI线程,则在线程池中反射调用订阅方法
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(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);
}
}
订阅方法的Method对象调用invoke(),是一种反射机制,参数中知道了订阅者对象,订阅者方法的事件参数对象,那么就可以直接调用到这个订阅方法了,也就达到发送事件接受到事件的循环了。
POSTING
未指定订阅方法线程的时候默认值,直接调用,post在哪个线程,这个订阅方法就在哪个线程
MAIN
指定订阅方法在UI线程中执行,如果当前为UI线程直接调用,否则利用MainThreadSupport对象加入UI线程消息队列 末尾执行,MainThreadSupport其实就是主线程的Handler对象,后面再讲
MAIN_ORDERED
这个和MAIN有啥区别呢?其实区别就是如果MainThreadSupport存在会优先加入UI线程消息队列末尾,否则才是立即执行
BACKGROUND
如果当前为主线程,加入后台线程执行,否则立即执行
ASYNC
不管当前什么线程,都在后台执行
post主干逻辑基本都说完了,再说下刚才那几个poster,MainThreadSupport、BackgroundPoster、AsyncPoster
他们都是接口,继承于Poster。
MainThreadSupport
public class HandlerPoster extends Handler implements Poster {
private final PendingPostQueue queue;
private final int maxMillisInsideHandleMessage;
private final EventBus eventBus;
private boolean handlerActive;
protected HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
super(looper);
this.eventBus = eventBus;
this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
// 创建一个自定义的队列
queue = new PendingPostQueue();
}
public void enqueue(Subscription subscription, Object event) {
// 获取存储pendingPost list中最末一个
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
// 获取到的pendingPost 入队
queue.enqueue(pendingPost);
// 当前handler对象是否还活动,如果没有活动就让它活动起来,这里的代码就相当于启动handler的作用
// 让handler处于发送、接受消息的循环中
if (!handlerActive) {
handlerActive = true;
// 发送空消息,在消息队列末尾,就会执行下面的handleMessage(),如果发送消息未成功,抛出异常
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
}
}
}
@Override
public void handleMessage(Message msg) {
boolean rescheduled = false;
try {
// 获取手机开机到现在的时间(毫秒),不包含睡眠时间
long started = SystemClock.uptimeMillis();
// 开启一个循环
while (true) {
// 获取队列头部的pendingPost
PendingPost pendingPost = queue.poll();
if (pendingPost == null) {
synchronized (this) {
// Check again, this time in synchronized
// 继续获取剩下队列头部的pendingPost
pendingPost = queue.poll();
if (pendingPost == null) {
// 如果获取了两次都是null,那么handlerActive = false;跳出方法
handlerActive = false;
return;
}
}
}
// 通过反射调用订阅者对象的订阅方法
eventBus.invokeSubscriber(pendingPost);
// 计算反射调用这个订阅方法的执行耗费时间(毫秒)
long timeInMethod = SystemClock.uptimeMillis() - started;
// 默认最大调用时间间隔是10毫秒,如果小于就继续循环从队列中取订阅方法反射调用,
// 如果大于就把剩下需要调用的加入消息队列末尾,然后又来执行handleMessage(),
// 因为这是在UI线程中进行的,如果调用时间过长,很容易出现ANR,所以把剩下没
// 调用完的加入消息队列末尾,让UI的其他操作先执行,防止阻塞
if (timeInMethod >= maxMillisInsideHandleMessage) {
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
// 因为已经加入了队列末尾,所有这个方法没有作用了可以退出去了
rescheduled = true;
return;
}
}
} finally {
handlerActive = rescheduled;
}
}
}
BackgroundPoster
final class BackgroundPoster implements Runnable, Poster {
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;
// 把当前BackgroundPoster对象放入线程池中并执行
eventBus.getExecutorService().execute(this);
}
}
}
@Override
public void run() {
try {
try {
while (true) {
// 从PendingPostQueue中取头部PendingPost,如果取两次都为null,退出方法
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;
}
}
}
AsyncPoster
class AsyncPoster implements Runnable, Poster {
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);
}
}
接下来看下注销事件
我们安卓中一般都会在Activity或者Fragment注册事件,如果不注销肯定会发生内存泄漏,导致内存溢出,
unregister()
/**
* 储存事件及对应方法;
* key是事件的Class对象,value是订阅者及订阅的方法集合
*/
private final Map, CopyOnWriteArrayList> subscriptionsByEventType;
/**
* 储存订阅者及事件Class对象;
* 用于判断订阅者是否注册过
*/
private final Map
/** Unregisters the given subscriber from all event classes. */
public synchronized void unregister(Object subscriber) {
List> 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());
}
}
/** Only updates subscriptionsByEventType, not typesBySubscriber! Caller must update typesBySubscriber. */
private void unsubscribeByEventType(Object subscriber, Class> eventType) {
List 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--;
}
}
}
}
subscriptionsByEventType这个很多地方都出现过,保存事件及对应订阅方法的,注销其实就是把这个订阅者和相关方法移除掉,
哈哈,是不是想到判断当前是否注册过的那个方法了,看下源码
public synchronized boolean isRegistered(Object subscriber) {
return typesBySubscriber.containsKey(subscriber);
}
明白了吧!
到这里EventBus这个优秀的框架主干都解析完了,我可能很多地方没描述清楚,不过小伙伴们懂逻辑原理就行了,细微的方法可以下面慢慢看下了。
EventBus说白了就是根据注解把相关的方法都保存在一个HashMap里面,key为事件Class对象,value为订阅者及相关订阅方法的集合,发送事件的时候就根据这个事件的Class对象从HashMap中拿出来一个一个循环的反射调用订阅者的订阅方法。
好了,又可以愉快玩耍了