源码备注地址:
https://github.com/panshimu/EventBus
1.注册:EventBus.getDefault().register(this);
第一步:查找所有订阅者中标有Subscribe注解的方法,然后获取该方法中的所有属性封装到SubscriberMethod中,放到List集合 subscriberMethods 中。
第二步:遍历subscriberMethods集合,根据订阅者和SubscriberMethod构建一个Subscription,并且根据方法参数类型够着一个List集合CopyOnWriteArrayList存储
Subscription,并以方法参数class类型为key,CopyOnWriteArrayList为value存贮到Map集合subscriptionsByEventType中。
第三步:根据订阅者创建一个List集合subscribedEvents用于存储该订阅者下所有类型参数class的集合,并且把这个订阅者和这个集合存储到map集合typesBySubscriber中,key是订阅者,value是subscribedEvents集合。
register()的任务到这里就完毕了。
2.发送: EventBus.getDefault().post("miaozi");
post就相对比较简单了。
首先是根据发送的数据类型 获取对应的class对象,根据class对象在subscriptionsByEventType中查找,得到CopyOnWriteArrayList中存储的Subscription,然后遍历Subscription订阅者得到具体的订阅者就可以得到绑定的SubscriberMethod,里面有很多的参数,得到其中的method方法就可以直接invoke了。
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
这样就能成功的发送消息了。
里面还有一些讲究,比如在子线程发送等等,就是用了handler和线程池的模式来处理的。大家可以自己阅读源码,应该不难看懂。
3.注销:EventBus.getDefault().unregister(this);
注销及更简单了,根据订阅者在typesBySubscriber获取所有方法参数Class,然后遍历Class,再根据class在subscriptionsByEventType中查找所有的Subscription,然后一个一个删除就好了。代码如下,很简单:
public synchronized void unregister(Object subscriber) {
//根据订阅者class删除
List<Class<?>> 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());
}
}
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
//根据订阅者 中的方法参数class
List<Subscription> 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--;
}
}
}
}
相信大家一看就懂。
到这里就结束了。具体的源码备注在开头的github连接上。
ok
总结:
注册:
1.遍历所有注册类带有Subscribe注解方法,封装成SubscriberMethod存贮到List<SubscriberMethod>集合中。
2.遍历List<SubscriberMethod>,创建Subscription对象存贮 注册类 和 subscriberMethod。根据方法参数类型,创建Map<方法参数类型,CopyOnwriteArrayList<Subscription>>,存贮Subscription。然后再次创建一个Map<注册类,方法参数集合>,这个主要是为了方便移除。
网友评论