我們來分析Eventbus3.0 的 post()方法
subscriptionsByEventType : key 為訂閱事件event Class , value 為 所有訂閱者的數(shù)據(jù) , 可以根據(jù) EventType 查找訂閱事件捎谨。
typesBySubscriber : key 為當(dāng)前項目有哪些Java類 注冊了事件 , value 為這些類都訂閱了哪些接收方法 , 根據(jù)我們的訂閱對象找到 EventType。
/** Posts the given event to the event bus. */
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);
}
} finally {
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
currentPostingThreadState 是一個 ThreadLocal 對象 他會在每個線程有自己的 PostingThreadState 沒有存過就創(chuàng)建一個默認(rèn)的對象;
final static class PostingThreadState {
//通過post方法參數(shù)傳入的事件集合
final List<Object> eventQueue = new ArrayList<Object>();
boolean isPosting; //是否正在執(zhí)行postSingleEvent()方法
boolean isMainThread;
Subscription subscription;
Object event;
boolean canceled;
}
PostingThreadState 封裝了發(fā)送需要的一些數(shù)據(jù)
postSingleEvent()里會調(diào)用postSingleEventForEventType()
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
CopyOnWriteArrayList<Subscription> subscriptions;
synchronized (this) {
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
for (Subscription subscription : subscriptions) {
postingState.event = event;
postingState.subscription = subscription;
boolean aborted = false;
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;
}
subscriptionsByEventType
key 事件類型
value 接收的事件的方法List
postToSubscription()
會根據(jù)不同的線程來執(zhí)行不同的方法向訂閱者發(fā)送事件其中invokeSubscriber() 是根據(jù)方法名來反射操作的;
unregister
/** Unregisters the given subscriber from all event classes. */
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());
}
}
typesBySubscriber
是個map key 為我們傳入的this 也就是當(dāng)前類
value是當(dāng)前類所有接收事件方法class類型
/** Only updates subscriptionsByEventType, not typesBySubscriber! Caller must update typesBySubscriber. */
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--;
}
}
}
}
subscriptionsByEventType map對象 , 根據(jù)我們的eventType 來取出訂閱這個事件所有方法, 判斷是當(dāng)前要取消注冊這個事件的元素就在集合remove掉;
總結(jié) :
發(fā)送過程
- 利用localThread來實現(xiàn)取出當(dāng)前線程的封裝收
- 循環(huán)一個map取出當(dāng)前事件的所有訂閱者
- 利用反射發(fā)送事件
取消注冊邏輯
- 利用2個map判斷其事件類型,來移除要解注冊元素
注冊邏輯
- 利用SubscriberMethodFinder 對象來取出 List<SubscriberMethod> 集合,他是查看當(dāng)前類有哪些接收事件
- 然后遍歷他,把接收事件的方法 存入2個總的map中;
注意
1.eventBus 不要多次注冊,否則會導(dǎo)致方法接收被多次調(diào)用