EventBus 粘性事件,源码解析
1 Eeventbus 在处理消息通信的时候是比通常的出发办法好用的得,最新使用了eventbus 的粘性事件 首先你需要传递一个消息bean,
EventBus.getDefault().postSticky(messageStatusResultBean);
2 调用上面的方法 就会把这个objoct 放到里面
private final Map<Class<?>, Object> stickyEvents;
3 在要处理的地方获取消息bean
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN) public void getPushMsg(MessageStatusResultBean messageStatusResultBean) { }
4 粘性事件要收到移除
EventBus.getDefault().removeStickyEvent(MessageStatusResultBean.class);
5 他是如何调用的呢,首先我们会在oncreate的时候做这样的一件事情
if (!EventBus.getDefault().isRegistered(this)) EventBus.getDefault().register(this);
6 然后我们来看看 register 这个方法 调用了subcribe方法
public void register(Object subscriber) { Class<?> subscriberClass = subscriber.getClass(); List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass); synchronized (this) { for (SubscriberMethod subscriberMethod : subscriberMethods) { subscribe(subscriber, subscriberMethod); //调用了subcribe方法
} } }
7 接做看 subscribe 方法
// Must be called in synchronized block private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) { //.... if (subscriberMethod.sticky) { if (eventInheritance) { // Existing sticky events of all subclasses of eventType have to be considered. // Note: Iterating over all events may be inefficient with lots of sticky events, // thus data structure should be changed to allow a more efficient lookup // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>). Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet(); for (Map.Entry<Class<?>, Object> entry : entries) { Class<?> candidateEventType = entry.getKey(); if (eventType.isAssignableFrom(candidateEventType)) { Object stickyEvent = entry.getValue(); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } } else { Object stickyEvent = stickyEvents.get(eventType); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } }
8 接下来走到
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); } }
9 接下来就是去处理了,会根据线程模式的不同处理不同的事件 ,在主线程是通过handle来处理的
@Override public void handleMessage(Message msg) { boolean rescheduled = false; try { long started = SystemClock.uptimeMillis(); while (true) { PendingPost pendingPost = queue.poll(); if (pendingPost == null) { synchronized (this) { // Check again, this time in synchronized pendingPost = queue.poll(); if (pendingPost == null) { handlerActive = false; return; } } } eventBus.invokeSubscriber(pendingPost); long timeInMethod = SystemClock.uptimeMillis() - started; if (timeInMethod >= maxMillisInsideHandleMessage) { if (!sendMessage(obtainMessage())) { throw new EventBusException("Could not send handler message"); } rescheduled = true; return; } } } finally { handlerActive = rescheduled; } }