文章目录
- EventBus分析
- EventBus执行流程分析
- EventBus源码分析
- EventBus核心属性
- 注册
- EventBus#getDefault()
- EventBus#register()
- SubscriberMethodFinder#findSubscriberMethods()
- SubscriberMethodFinder#findUsingInfo()
- SubscriberMethodFinder#findUsingReflectionInSingleClass()
- SubscriberMethodFinder#getMethodsAndRelease()
- EventBus#subscribe()
- 反注册
- EventBus#unregister()
- EventBus#unsubscribeByEventType()
- 发布事件
- EventBus#post()
- EventBus#postSingleEvent()
- EventBus#postSingleEventForEventType()
- EventBus#postToSubscription()
- EventBus#postSticky()
- 优秀博客
EventBus分析
EventBus执行流程分析
EventBus基本使用
//在Activity里使用EventBus
@Override
protected void onStart() {
super.onStart();
//注册
EventBus.getDefault().register(this);
}
public void btnClick(View v) {
//发布事件
EventBus.getDefault().post(new MessageEvent<String>(100, "hello 这是一条普通事件"));
}
//订阅方法
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent<String> event) {
if (event.getCode() == 100) {
tv_msg.setText(event.getData());
}
}
//订阅方法
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent2<String> event) {
if (event.getCode() == 100) {
tv_msg.setText(event.getData());
}
}
@Override
protected void onStop() {
super.onStop();
//反注册
EventBus.getDefault().unregister(this);
}
事件流向
订阅者和订阅事件关系
上面的代码里,订阅者subscriber是Activity
,监听了两个事件MessageEvent
和MessageEvent2
,当发布事件后,会收到2个数据。
订阅者通过register()
方法注册,一个订阅者可以对应多个事件,通过一个Map结构维护。
private final Map<Object, List<Class<?>>> typesBySubscriber;
订阅事件和订阅者关系
在Android中,一个事件可能被多个subscriber订阅,当发布事件时,会查找所有订阅了该事件的subscriber,并调用其中的event方法,通过一个Map结构维护。
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
粘性事件关系
发布的粘性事件会将事件类型和事件保存在一个Map结构中,注册时订阅消息会从stickyEvents
取出消息并执行。
private final Map<Class<?>, Object> stickyEvents;
EventBus源码分析
EventBus核心属性
//key为订阅者对象,value为订阅事件类型集合(Event类型)
private final Map<Object, List<Class<?>>> typesBySubscriber;
//订阅信息类,包含订阅者对象和订阅方法
final class Subscription {
final Object subscriber;
final SubscriberMethod subscriberMethod;
}
//key为事件类型,value为Subscription对象
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
//key为订阅者的class对象,value为订阅者中的所有订阅方法
private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();
注册
EventBus#getDefault()
//单例模式,获取EventBus对象
public static EventBus getDefault() {
EventBus instance = defaultInstance;
if (instance == null) {
synchronized (EventBus.class) {
instance = EventBus.defaultInstance;
if (instance == null) {
instance = EventBus.defaultInstance = new EventBus();
}
}
}
return instance;
}
EventBus#register()
//注册订阅者
public void register(Object subscriber) {
//获取的class对象
Class<?> subscriberClass = subscriber.getClass();
//获得注册类的所有订阅方法
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
//遍历订阅方法
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
//关联注册类和订阅方法
subscribe(subscriber, subscriberMethod);
}
}
}
SubscriberMethodFinder#findSubscriberMethods()
//获取所有订阅方法
//必须是@Subscribe注解,public修饰,一个参数
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
//先从缓存中获取订阅方法
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
//ignoreGeneratedIndex默认为false
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;
}
}
SubscriberMethodFinder#findUsingInfo()
//若findState缓存订阅方法信息,则使用findState里的缓存,否则调用findUsingReflectionInSingleClass()获取订阅方法信息
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
//获取一个存储对象findState
FindState findState = prepareFindState();
//findState存储订阅者的class对象
findState.initForSubscriber(subscriberClass);
//findState.clazz就是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 {
//执行此处
findUsingReflectionInSingleClass(findState);
}
//需要遍历父类,修改findState.clazz为subscriberClass的父类的class对象
findState.moveToSuperclass();
}
//返回findState中保存的订阅方法,并释放findState
return getMethodsAndRelease(findState);
}
SubscriberMethodFinder#findUsingReflectionInSingleClass()
//通过反射获取订阅方法的信息
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
//获取订阅者中的所有方法
methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
...
}
//遍历方法
for (Method method : methods) {
//获取方法的修饰符
int modifiers = method.getModifiers();
//方法是public类型,但是不能是abstract、static等
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);
//若方法有@Subscribe注解,则就是订阅者中的订阅方法
if (subscribeAnnotation != null) {
//获取订阅方法中的第一个参数类型,依旧是订阅的事件类型
Class<?> eventType = parameterTypes[0];
//checkAdd用于判断FindState是否添加过该事件
if (findState.checkAdd(method, eventType)) {
//获取线程模式
ThreadMode threadMode = subscribeAnnotation.threadMode();
//将订阅方法中的信息(如:订阅方法、事件类型、线程模式、优先级、粘性事件等)封装成SubscriberMethod对象,并保存到到findState中的subscriberMethods集合里
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode, subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
}
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
//参数个数超过1个时,抛出异常
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时,抛出异常
String methodName = method.getDeclaringClass().getName() + "." + method.getName();
throw new EventBusException(methodName + " is a illegal @Subscribe method: must be public, non-static, and non-abstract");
}
}
}
SubscriberMethodFinder#getMethodsAndRelease()
private List<SubscriberMethod> getMethodsAndRelease(FindState findState) {
//获取findState中的subscriberMethods
List<SubscriberMethod> subscriberMethods = new ArrayList<>(findState.subscriberMethods);
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#subscribe()
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
//获取订阅方法的事件类型
Class<?> eventType = subscriberMethod.eventType;
//将订阅者和订阅方法封装成一个Subscription对象
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
//subscriptionsByEventType是HashMap结构,key为事件类型,value为Subscription对象
//获取该事件的所有订阅者信息
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
//若不存在
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);
}
}
//添加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是HashMap结构,key为订阅者对象,value为事件集合
//获取该订阅者的事件集合
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
//添加到集合中
subscribedEvents.add(eventType);
//是否支持粘性事件
if (subscriberMethod.sticky) {
if (eventInheritance) {
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#unregister()
public synchronized void unregister(Object subscriber) {
//获取当前订阅者的所有事件类型集合
List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
//若集合不为null
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#unsubscribeByEventType()
//解除事件订阅
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
//根据当前事件类型,获取订阅者集合
List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
//若集合不为null
if (subscriptions != null) {
int size = subscriptions.size();
//遍历订阅者集合
for (int i = 0; i < size; i++) {
//获取Subscription对象,该对象包含订阅者对象和订阅方法的所有信息
Subscription subscription = subscriptions.get(i);
//若找到该订阅者,则移除订阅者
if (subscription.subscriber == subscriber) {
subscription.active = false;
subscriptions.remove(i);
i--;
size--;
}
}
}
}
发布事件
EventBus#post()
//发布事件
public void post(Object event) {
//获取当前线程的PostingThreadState对象
//postingState对象包含:事件队列、线程状态、是否正在发送的标识等
PostingThreadState postingState = currentPostingThreadState.get();
//获取事件队列
List<Object> eventQueue = postingState.eventQueue;
//将事件加入到事件队列中
eventQueue.add(event);
//当前事件是否正在发送
if (!postingState.isPosting) {
//是否在主线程
postingState.isMainThread = isMainThread();
//isPosting设置为true
postingState.isPosting = true;
//是否取消
if (postingState.canceled) {
throw new EventBusException("Internal error. Abort state was not reset");
}
try {
//遍历队列,队列不为null,进入循环
while (!eventQueue.isEmpty()) {
//分发事件
postSingleEvent(eventQueue.remove(0), postingState);
}
} finally {
//重置状态
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
EventBus#postSingleEvent()
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
//获取事件对象的class
Class<?> eventClass = event.getClass();
boolean subscriptionFound = false;
//是否查看所有的继承关系
if (eventInheritance) {
//lookupAllEventTypes()获取父类的所有事件类型
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);
}
if (!subscriptionFound) {
if (logNoSubscriberMessages) {
logger.log(Level.FINE, "No subscribers registered for event " + eventClass);
}
//若没有订阅事件,则发送NoSubscriberEvent
if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) {
post(new NoSubscriberEvent(this, event));
}
}
}
EventBus#postSingleEventForEventType()
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
CopyOnWriteArrayList<Subscription> subscriptions;
synchronized (this) {
//获取当前事件的所有订阅者
subscriptions = subscriptionsByEventType.get(eventClass);
}
//若集合不为null
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#postToSubscription()
//处理事件
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
//根据EventBus线程模式处理对应事件
switch (subscription.subscriberMethod.threadMode) {
case POSTING:
//默认线程模式,在哪个线程发送事件,就在哪个线程处理事件
//直接通过反射执行
invokeSubscriber(subscription, event);
break;
case MAIN:
//如果是主线程,则直接执行,如果是子线程,则通过Handler切换主线程执行
if (isMainThread) {
//主线程中,直接通过反射执行
invokeSubscriber(subscription, event);
} else {
//通过Handler切换到主线程,在进行处理
mainThreadPoster.enqueue(subscription, event);
}
break;
case MAIN_ORDERED:
//无论哪个线程,都先加入队列后,通过Handler执行
if (mainThreadPoster != null) {
mainThreadPoster.enqueue(subscription, event);
} else {
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);
}
}
//直接通过反射执行
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);
}
}
EventBus#postSticky()
//发布粘性事件
public void postSticky(Object event) {
synchronized (stickyEvents) {
//将事件类型和事件放入stickyEvents中
stickyEvents.put(event.getClass(), event);
}
post(event);
}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
//...
//判断订阅方法是否粘性事件
if (subscriberMethod.sticky) {
//是否查找父类
if (eventInheritance) {
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);
}
}
}