基于eventbus 2.4.0
项目中很多地方用到EventBus
大体的使用 就是这样的几段代码
// 注册
EventBus.getDefault().register(this);
// 发送
EventBus.getDefault().post(new Event());
// 响应
public void onEventMainThread(Event event) {
}
// 取消注册
EventBus.getDefault().unregister(this);
EventBus.getDefault()
利用单例模式获取的是EventBus实例。
register
方法
// 采用的是订阅者模式
private synchronized void register(Object subscriber, boolean sticky, int priority) {
// findSubscriberMethods 通过反射获取subscriber的 onEventMainThread方法
List<SubscriberMethod> subscriberMethods = this.subscriberMethodFinder.findSubscriberMethods(subscriber.getClass());
// 获取迭代器
Iterator i$ = subscriberMethods.iterator();
// 遍历订阅
while(i$.hasNext()) {
SubscriberMethod subscriberMethod = (SubscriberMethod)i$.next();
// 订阅
this.subscribe(subscriber, subscriberMethod, sticky, priority);
}
}
SubscriberMethod
类中保存了 响应Method
订阅方法里是怎么做的?大体思路是按照优先级把一个个Subscription对象(包含注册对象)放入EventType对应的List中,再把注册对象的EventType放到对应的List中。
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod, boolean sticky, int priority) {
Class<?> eventType = subscriberMethod.eventType;
CopyOnWriteArrayList<Subscription> subscriptions = (CopyOnWriteArrayList)this.subscriptionsByEventType.get(eventType);
// 利用订阅者对象和响应方法创建一个新的对象
Subscription newSubscription = new Subscription(subscriber, subscriberMethod, priority);
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList();
this.subscriptionsByEventType.put(eventType, subscriptions);
} else if (subscriptions.contains(newSubscription)) {
// 一个对象只允许注册一次
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event " + eventType);
}
int size = subscriptions.size();
// 添加到此事件对应的list里
for(int i = 0; i <= size; ++i) {
if (i == size || newSubscription.priority > ((Subscription)subscriptions.get(i)).priority) {
subscriptions.add(i, newSubscription);
break;
}
}
// 通过注册的对象 获取注册的event类对象
List<Class<?>> subscribedEvents = (List)this.typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList();
this.typesBySubscriber.put(subscriber, subscribedEvents);
}
((List)subscribedEvents).add(eventType);
if (sticky) {
// sticky 默认false 暂时不研究
Map var11 = this.stickyEvents;
Object stickyEvent;
synchronized(this.stickyEvents) {
stickyEvent = this.stickyEvents.get(eventType);
}
if (stickyEvent != null) {
this.postToSubscription(newSubscription, stickyEvent, Looper.getMainLooper() == Looper.myLooper());
}
}
}
取消注册大体就是反过来清空。
复杂的是发送事件的过程,涉及到线程切换。
public void post(Object event) {
EventBus.PostingThreadState postingState = (EventBus.PostingThreadState)this.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()) {
// // 不断循环来发送事件
this.postSingleEvent(eventQueue.remove(0), postingState);
}
} finally {
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
重点看 postSingleEvent
主要是把注册对象的EventType对应的List中取出,然后根据不同的线程进行分发。
private void postSingleEvent(Object event, EventBus.PostingThreadState postingState) throws Error {
Class<?> eventClass = event.getClass();
boolean subscriptionFound = false;
if (this.eventInheritance) {
// 遍历父类event 默认false
List<Class<?>> eventTypes = this.lookupAllEventTypes(eventClass);
int countTypes = eventTypes.size();
for(int h = 0; h < countTypes; ++h) {
Class<?> clazz = (Class)eventTypes.get(h);
subscriptionFound |= this.postSingleEventForEventType(event, postingState, clazz);
}
} else {
// 继续调用postSingleEventForEventType执行
subscriptionFound = this.postSingleEventForEventType(event, postingState, eventClass);
}
if (!subscriptionFound) {
if (this.logNoSubscriberMessages) {
Log.d(TAG, "No subscribers registered for event " + eventClass);
}
if (this.sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) {
this.post(new NoSubscriberEvent(this, event));
}
}
}
重点是 postSingleEventForEventType
根据不同的线程分发
private boolean postSingleEventForEventType(Object event, EventBus.PostingThreadState postingState, Class<?> eventClass) {
CopyOnWriteArrayList subscriptions;
synchronized(this) {
// 获取event对应的 所有注册过的对象
subscriptions = (CopyOnWriteArrayList)this.subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
Iterator i$ = subscriptions.iterator();
while(i$.hasNext()) {
// 遍历分发事件执行postToSubscription
Subscription subscription = (Subscription)i$.next();
postingState.event = event;
postingState.subscription = subscription;
boolean aborted = false;
try {
this.postToSubscription(subscription, event, postingState.isMainThread);
aborted = postingState.canceled;
} finally {
postingState.event = null;
postingState.subscription = null;
postingState.canceled = false;
}
if (aborted) {
break;
}
}
return true;
} else {
return false;
}
}
重点是 postToSubscription
根据订阅方法指定的threadMode信息来执行不同的分发。
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
switch(subscription.subscriberMethod.threadMode) {
case PostThread:
this.invokeSubscriber(subscription, event);
break;
case MainThread:
if (isMainThread) {
this.invokeSubscriber(subscription, event);
} else {
this.mainThreadPoster.enqueue(subscription, event);
}
break;
case BackgroundThread:
if (isMainThread) {
this.backgroundPoster.enqueue(subscription, event);
} else {
this.invokeSubscriber(subscription, event);
}
break;
case Async:
this.asyncPoster.enqueue(subscription, event);
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
}
}
mainThreadPoster
继承自Handler
,当调用它的enqueue
方法的时候,发送一个事件并在它自身的handleMessage
方法中从队列中取值并进行处理,从而达到在主线程中分发事件的目的。backgroundPoster也是同理。