Android 注解系列之EventBus3“加速引擎“(五)

2824145-7edc9c3775ff1b3d.jpg
bus.jpg

前言

在上篇文章 Android 注解系列之 EventBus3 原理(四)中我们讲解了 EventBus3 的内部原理,在该篇文章中我们将讲解 EventBus3 中的 “加速引擎"---索引类。阅读该篇文章我们能够学到如下知识点。

  • EventBus3 索引类出现的原因
  • EventBus3 索引类的使用
  • EventBus3 索引类生成的过程
  • EventBus3 混淆注意事项

对 APT 技术不熟悉的小伙伴,可以查看文章 Android-注解系列之APT工具(三)

前景回顾

Android 注解系列之 EventBus3 原理(四)中,我们特别指出在 EventBus3 中优化了 SubscriberMethodFinder 获取类中包含 @Subscribe 注解的订阅方法的流程。使其能在 EventBus.register() 方法调用之前就能知道相关订阅事件的方法,这样就减少了程序在运行期间使用反射遍历获取方法所带来的时间消耗。优化点如下图中 红色虚线框 所示:

2824145-775ec7aee8132189.jpg
EventBus3优化.jpg

EventBus 作者 Markus Junginger 也给出了使用索引类前后 EventBus 的效率对比,如下图所示:

2824145-97e436b273ff2a1d.png
eventbus3-registration-perf-nexus9m.png

从上图中,我们可以使用索引类后,EventBus 的效率有着明显的提升,而效率提升的背后,正是使用了 APT 技术所创建的索引类。那么接下来我们就来看一看 EventBus3 中是如何结合 APT 技术来进行优化的。

关键代码

阅读过 EventBus3 源码的小伙伴应该都知道,在 EventBus3 中获取类中包含 @Subscribe 注解的订阅方法有两种方式。

  • 第一种:是直接在程序运行时反射获取
  • 第二种:就是通过索引类。

而使用索引类的关键代码为 SubscriberMethodFinder 中的
getSubscriberInfo() 方法与 findUsingInfo() 方法 。
我们分别来看这两个方法。

findUsingInfo 方法
    private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
        FindState findState = prepareFindState();
        findState.initForSubscriber(subscriberClass);
        while (findState.clazz != null) {
            //?关键代码,从索引类中获取 SubscriberInfo
            findState.subscriberInfo = getSubscriberInfo(findState);
            //方式1:如果 subscriberInfo 不为空,则从该对象中获取 SubscriberMethod 对象
            if (findState.subscriberInfo != null) {
                SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
                for (SubscriberMethod subscriberMethod : array) {
                    if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
                        findState.subscriberMethods.add(subscriberMethod);
                    }
                }
            } else {
                //方式2:如果 subscriberInfo 为空,那么直接通过反射获取
                findUsingReflectionInSingleClass(findState);
            }
            findState.moveToSuperclass();
        }
        return getMethodsAndRelease(findState);
    }

我们能从该方法中获得以下信息:

  • EventBus3 中默认会调用 getSubscriberInfo() 方法去获取 subscriberInfo 对象信息。
  • 如果 subscriberInfo 不为空,则会从该对象中获取 SubscriberMethod 数组。
  • 如果 subscriberInfo 为空,那么会直接通过反射去获取 SubscriberMethod 集合信息。

SubscriberMethod 类中含有 @Subscribe 注解的方法信息封装(优先级,是否粘性,线程模式,订阅的事件),以及当前方法的 Method 对象(java.lang.reflect 包下的对象)。

也就说 EventBus 是否通过反射获取信息,是由 getSubscriberInfo()方法来决定,那么我们查看该方法。

getSubscriberInfo 方法
    private SubscriberInfo getSubscriberInfo(FindState findState) {
        if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
            SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
            if (findState.clazz == superclassInfo.getSubscriberClass()) {
                return superclassInfo;
            }
        }
        //?这里是EventBus3中优化的关键,索引类
        if (subscriberInfoIndexes != null) {
            for (SubscriberInfoIndex index : subscriberInfoIndexes) {
                SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
              
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值