美文网首页程序员Android开发android技术专栏
手写EventBus框架——源码分析2

手写EventBus框架——源码分析2

作者: wenld_ | 来源:发表于2017-03-26 22:57 被阅读271次

    路漫漫其修远兮

    01. 手写EventBus框架——源码分析1
    02. 手写EventBus框架——源码分析2
    03. 手写EventBus框架——动手_整体架构设计
    04. 手写EventBus框架——动手_终结


    上篇文章 手写EventBus框架——源码分析1 从EventBus的源码出发 分析了 注册,取消注册、发布 和缓存订阅事件等主体功能,了解它的一个实现机制以及事件总线的设计。

    基本上分析完上一篇文章就已经可以实现基本的EventBus了,然而,EventBus是个优秀的框架,有很多地方值得学习,这篇文章接着对源码进行解析补充:

    • Sticky 粘性事件实现
    • 事件优先级实现
    • 其他一些

    o.O Sticky粘性

    什么是粘性事件? **
    相信大部分同学都知道,像EventBus会经常用到,包括广播也是有粘性事件分发的这个概念的。那么针对于不熟悉的同学我就简单说一下,
    o.O 真的是简单说一下~** :简单讲,就是在注册之前分发事件,而后事件注册以后也能接收到分发的事件。
    大白话:先post 在 register, 也能收到分发事件。

    上篇分析到:post 方式的实现机制是:通过反射立刻执行我们订阅的方法。
    然而粘性事件的性质是 分发事件发生在订阅事件之前,订阅事件发生在分发事件之后,那么带着这个疑问,我们来看一下:

    先发布postSticky

        public void postSticky(Object event) {
            synchronized (stickyEvents) {
            //加入粘性列表
                stickyEvents.put(event.getClass(), event);
            }
            post(event);
        }
    

    注册粘性:

        public void register(Object subscriber) {
          //...
                    subscribe(subscriber, subscriberMethod);
        }
        
        private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
           //判断是粘性事件
            if (subscriberMethod.sticky) {
                if (eventInheritance) {
                   //循环
                    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);
                }
            }
        }    
    

    ** ~ 柳暗花明又一村 **
    分析完后大叹一声:原来如此!
    那粘性事件的流程我们就比较清晰明了了。

    流程

    1. 发布时:将 发布事件 缓存起来;
    2. 当粘性事件被订阅的时候 : 检查缓存器,如果相匹配 则执行该订阅事件,从而执行一次完整的粘性事件。

    注意
      这边执行完粘性事件以后 没有将缓存清除,那么下次再注册该粘性方法时还会执行。那么这时候需要调用removeStickyEvent清除粘性缓存。

    o.O 事件优先级

    其中有事件优先级的一个概念。看一下它的一个设计

        public void register(Object subscriber) {
            Class<?> subscriberClass = subscriber.getClass();
       //...
                    subscribe(subscriber, subscriberMethod);
      //...
        }
    
        private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
            Class<?> eventType = subscriberMethod.eventType;
      //...
            List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
            if (subscribedEvents == null) {
                subscribedEvents = new ArrayList<>();
                typesBySubscriber.put(subscriber, subscribedEvents);
            }
        //....
        }
    

    比较简单,控制缓存列表的顺序。
    注意:
     这边的优先级 只是针对 订阅类型 也就是eventType

    o.O 其他一些

    比较简单,也没什么好讲的 ...

    下一篇: 03. 手写EventBus框架——动手_整体架构设计


    希望我的文章不会误导在观看的你,如果有异议的地方欢迎讨论和指正。
    如果能给观看的你带来收获,那就是最好不过了。

    人生得意须尽欢, 桃花坞里桃花庵
    点个关注呗,对,不信你点试试?

    相关文章

      网友评论

        本文标题:手写EventBus框架——源码分析2

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