美文网首页
EventBus的粘性事件原理

EventBus的粘性事件原理

作者: 孙大硕 | 来源:发表于2019-10-08 16:22 被阅读0次

    虽然EventBus现在有点过时了,但是其蕴含的思想还是很值得我们去学习的。

    个人认为EventBus的魅力在于避免了回调带来的接口爆炸,今天来看一下EventBus的粘性事件的原理。

    1. 粘性事件的用法:

    • 订阅的时候
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
        public fun onEvent() {
    
        }
    

    很简单,就是在订阅的时候加上sticky = true

    • 发布的时候
    EventBus.getDefault().postSticky(this)
    

    只是将一般的post改为postSticky

    2. 事件的接收

    • 一般事件的接收,当我们调用EventBus.getDefault().register(this)的时候,会通过通过注解去拿我们注册的方法,代码如下:
    List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
    

    将方法拿出来之后就会和具体的事件类型绑定:

    subscriptionsByEventType.put(eventType, subscriptions);
    

    当我们调用post的时候,会去刚才的缓存里查询:

     subscriptions = subscriptionsByEventType.get(eventClass);
    

    然后根据反射调用我们注册的方法。

    所谓粘性事件就是在事件发送时,接收者还不存在,当接收方注册的时候再处理该事件。

    • 粘性事件的接收,在我们调用postSticky,会把粘性事件先保存下来:
    stickyEvents.put(event.getClass(), event);
    

    当EventBus遍历订阅方法时根据注解判断当前方法是否是sticky,如果是的:

    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);
                }
            }
    

    就拿到这个粘性事件,直接调用该订阅方法:

    postToSubscription(subscription, event, postingState.isMainThread);
    

    相关文章

      网友评论

          本文标题:EventBus的粘性事件原理

          本文链接:https://www.haomeiwen.com/subject/mjmbpctx.html