EventBus 粘性事件,源码解析

Posted 肖恩大神_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
        }
    }

 

以上是关于EventBus 粘性事件,源码解析的主要内容,如果未能解决你的问题,请参考以下文章

EventBus3.0源码解析

Abp领域事件(EventBus)源码解析

EventBusEventBus 源码解析 ( 事件发送 | postToSubscription 方法 | EventBus 线程模式处理细节 )

EventBusEventBus 源码解析 ( 事件发送 | EventBus.post 方法 | EventBus.postSingleEvent 方法 )

EventBus 使用 demo 粘性事件与正常事件的使用

EventBus的使用和源码解析