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

路漫漫其修远兮

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框架——动手_整体架构设计

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

人生得意须尽欢, 桃花坞里桃花庵
点个关注呗,对,不信你点试试?
    原文作者:wenld_
    原文地址: https://www.jianshu.com/p/f40235397460
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞