自EventBus问世后,带给众码农福利多多。不仅简而易用,而且代码简洁明了。虽然Activity之间以及fragment之间的消息通信可以使用很多方式实现,比如广播,接口回调,但是与EventBus相比起来,还是觉得后者更加犀利。 发动机虽好用,可是一旦出了问题一脸懵逼,所以起码也要稍微明白发动力是怎么工作的吧。所以我打开EventBus的源码,开始十目一行的阅读,慢慢的分析,发现了EventBus的奥妙所在.
compile 'org.greenrobot:eventbus:3.0.0' //直接在项目中依赖
//都是声明了Map集合,虽然从这里看不出各个集合的用处,但是大概明白了EventBus是需要这些集合来存储事件的
private static final Map<Class<?>, List<Class<?>>> eventTypesCache = new HashMap<>();
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
private final Map<Object, List<Class<?>>> typesBySubscriber;
private final Map<Class<?>, Object> stickyEvents;
//1.首先看了最先使用的register方法
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();//获取注册类的类型
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);//获取该类中注册过的所有方法
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {//循环这些方法,并且传递给subscribe方法中
subscribe(subscriber, subscriberMethod);
}
}
}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
Class<?> eventType = subscriberMethod.eventType;//通过该方法获取到事件的类型
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);//获取存储全部方法的集合
if (subscriptions == null) {//如果集合为null,新建一个CopyOnWriteArrayList,把这个类型用map保存起来
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
} else {//如果集合不为null,检查一下是否在该类中已经注册了。
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
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;
}
}
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);//获取用该类作为key对应的value集合
if (subscribedEvents == null) {//如果没有的话就创建一个
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
subscribedEvents.add(eventType);//最后将注册的方法类型保存在这个集合中
}
//2.然后看了unregister方法是如何实现的
public synchronized void unregister(Object subscriber) {
List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);//获取该类的所有方法集合
if (subscribedTypes != null) {
for (Class<?> eventType : subscribedTypes) {//循环遍历去掉注册的类型
unsubscribeByEventType(subscriber, eventType);
}
typesBySubscriber.remove(subscriber);//去掉该类
} else {
Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
}
}
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
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--;
}
}
}
}
//3.最后看了post的使用原理
public void post(Object event) {
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()) {//无限循环取出消息发送
postSingleEvent(eventQueue.remove(0), postingState);//取一个去掉一个,然后传递给postSingleEvent方法
}
} finally {
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
Class<?> eventClass = event.getClass();
boolean subscriptionFound = false;
if (eventInheritance) {//如果有父类的话
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) {
Log.d(TAG, "No subscribers registered for event " + eventClass);
}
if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
eventClass != SubscriberExceptionEvent.class) {
post(new NoSubscriberEvent(this, event));
}
}
}
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 {
mainThreadPoster.enqueue(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);
}
}
总结:
1.所有注册的事件类型,都以键值对的方式存储在typesBySubscriber集合中。
2.register实际就是往map中添加注册的对象,unRegister则是从map中去掉注册的对象。
3.如果父类与子类也注册有同样类型的方法,两者都会同时执行。
4.注册的方法被唤起执行是通过反射机制实现的。

424

被折叠的 条评论
为什么被折叠?



