通过apt在编译期将所有被 @Subscribe注解的函数添加到MyEventBusIndex对象中。
在register过程中生成subscriptionsByEventType的数据。
在 post过程中通过subscriptionsByEventType数据查找对应的函数,然后再通过反射的方式调用。
1,普通post事件 : 直接发送
public void post(Object event) {
postSingleEventForEventType(event, event.getClass());
}
//遍历所有的订阅者,发送对应的事件
private void postSingleEventForEventType(Object event, Class<?> eventClass) {
CopyOnWriteArrayList<Subscription> subscriptions;
//获取eventBean对应的多个Subscribe事件
synchronized (this) {
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
for (Subscription subscription : subscriptions) {
//发送普通事件的时候不触发粘性事件
if (!subscription.subscriberMethod.isSticky()) {
postToSubscription(subscription, event);
}
}
}
}
//发送事件,主线程和异步
private void postToSubscription(final Subscription subscription, final Object event) {
switch (subscription.subscriberMethod.getThreadMode()) {
case POSTING: // 订阅、发布在同一线程
invokeSubscriber(subscription, event);
break;
case MAIN:
//事件发送方是主线程
if (Looper.myLooper() == Looper.getMainLooper()) {
invokeSubscriber(subscription, event);
} else {
//事件发送方是子线程
handler.post(new Runnable() {
@Override
public void run() {
invokeSubscriber(subscription, event);
}
});
}
break;
case ASYNC:
//发送方在主线程
if (Looper.myLooper() == Looper.getMainLooper()) {
executorService.execute(new Runnable() {
@Override
public void run() {
invokeSubscriber(subscription, event);
}
});
} else {
invokeSubscriber(subscription, event);
}
break;
}
}
//反射调用apt获取的方法
private void invokeSubscriber(Subscription subscription, Object event) {
try {
subscription.subscriberMethod.getMethod().invoke(subscription.subscriber, event);
} catch (Exception e) {
e.printStackTrace();
}
}
2,粘性事件 : 注册的时候发送
普通事件是先注册,后发送。而粘性事件相反,是先发送存数据,后注册的时候调函数。
如跳转activity传递参数
public void postSticky(Object event) {
stickyEvents.put(event.getClass(), event);
}
/**
* 订阅者的入口
*
* @param subscriber activity,fragment
*/
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
List<SubscriberMethod> subscriberMethods = findSubscriberMethods(subscriberClass);
for (SubscriberMethod method : subscriberMethods) {
subscribe(subscriber, method);
}
}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
Class<?> eventType = subscriberMethod.getEventType();
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
}
Subscription subscription = new Subscription(subscriber, subscriberMethod);
// if (subscriptions.contains(subscription)) {
// //粘性事件相关逻辑
// sticky(subscriberMethod, eventType, subscription);
// return;
// }
//根据优先级插队
int size = subscriptions.size();
for (int i = 0; i <= size; i++) {
if (i == size || subscriberMethod.getPriority() > subscriptions.get(i).subscriberMethod.getPriority()) {
if (!subscriptions.contains(subscription)) subscriptions.add(i, subscription);
break;
}
}
//订阅者类型集合
List<Class<?>> subscribeEvents = typeBySubscriber.get(subscriber);
if (subscribeEvents == null) {
subscribeEvents = new ArrayList<>();
typeBySubscriber.put(subscriber, subscribeEvents);
}
subscribeEvents.add(eventType);
//粘性事件入口
sticky(subscriberMethod, eventType, subscription);
}
/**
* 在register的时候,遍历当前类下所有Subscribe函数,查看是否有粘性事件
*/
private void sticky(SubscriberMethod subscriberMethod, Class<?> eventType, Subscription subscription) {
if (subscriberMethod.isSticky()) {
Object event = stickyEvents.get(eventType);
if (event != null) {
postToSubscription(subscription, event);
}
}
}