EventBus查找订阅者之注解处理器

想全面了解EventBus的童鞋可以参考这里:https://blog.youkuaiyun.com/wangchao1412/article/details/84629815

Subscriber Index(订阅者索引)是一个可选择的优化技术,用来加速初始化subscriber注册。

通过使用EventBus annotation processor(EventBus注解处理器),订阅者索引在编译期间就会被创建。虽然没有规定必须使用它,但是由于它在Android中最佳性能,官方推荐使用此方式。

如何使用Subscriber Index

添加依赖:

implementation 'org.greenrobot:eventbus:3.0.0'
//有了它就可以在编译时找subscribermethod了
annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.0.1'
在android中添加:

defaultConfig {
    javaCompileOptions {
        annotationProcessorOptions {
            //编译时会生成新文件,com.example.myapp表示路径,MyEventBusIndex类名
            arguments = [ eventBusIndex : 'com.example.myapp.MyEventBusIndex' ]
        }
    }
}
新文件会生成在build\generated\source\apt\debug下。

注册EventBus

//把生成的MyEventBusIndex注入EventBus中

EventBus.builder().addIndex(new MyEventBusIndex()).build().regist();

或者

EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus().register(this);

下面来从源码角度看一下EventBus是如何实现编译时注解的

 

AbstractProcessor的类

 

EventBus的编译时做的操作是在EventBusAnnotationProcessor中进行的,来看一下

@SupportedAnnotationTypes("org.greenrobot.eventbus.Subscribe")指明对@Subscribe进行筛选,会执行到process中,在这里进行操作生成什么样的文件。
@SupportedOptions(value = {"eventBusIndex", "verbose"})指明option的name,可以根据processingEnv.getOptions().get(key)去获取相应的值,这里eventBusIndex指的是我们生成文件的位置,这个我们需要在app的gradle中去自己设置。

下面是process方法,主要做的就是查找subscriberMethod和把信息按格式写入到java文件。

process中的collectSubscribers

 

在这里遍历Annotation,获取他的element,因为@subscribe是作用在Method上的,所以可以直接转成把element转成method,然后再checkHasNoErrors中进行筛除(如下)。在添加到methodsByClass中。

 

如果找到有符合的订阅者的话,就写入到java文件中。

createInfoIndexFile

 

右图是生成的文件格式,可以对照着右图解析左图的代码。

主要有导包的操作,还有固定的类的写法和方法的写法。需要动态写的是右图putIndex的写法,这里我们看一下是怎样写的。

writeIndexLines

writeCreateSubscriberMethods

这样我们就在指定的路径下生成了这个文件。

这里在静态代码块中直接调用了putIndex把SubscriberInfo添加到了map集合中。还提供了getSubScriberInfo去获取subscribe对应的subscriberInfo。

这里先看在putIndex的时候new 了一个SimpleSubScriberInfo,看一下

SimpleSubscriberInfo

这里呢把SubscriberMethodInfo[] methodInfos(装着订阅方法的信息)提供给自己,然后条用

super(subscriberClass, null, shouldCheckSuperclass);然后在getSubscriberMethods方法中去调用父类createSubscriberMethod

把SubscriberMethodInfo转成了SubscriberMethod。下面我们来看一下父类 AbstractSubscriberInfo。

 

AbstractSubscriberInfo

它实现的接口

可以看到,AbstractSubscriberInfo实现了接口中的getSubscriberClass方法和getSuperSubscriberInfo方法,而

getSubscriberMethods是在SimpleSubscriberInfo中实现的。

捋一下:在生成的文件MyEventBusIndex中getSubscriberInfo去获取SimpleSubscriberInfo,在这里是从map中取值,把SimpleSubscriberInfo转成了它的父类实现的接口SubscriberInfo,在SimpleSubscriberInfo中实现了getSubscriberMethods,在SimpleSubscriberInfo的父类AbstractSubscriberInfo中实现了getSubscriberClass和getSuperSubscriberInfo。所以直接拿到SubscriberInfo进行统一化管理取值更加方便。

SubscriberInfo

下面就看一下EventBus中是怎么对SubscribeInfo进行运用的。

点进去看一下

再点进去

这里的subscriberInfoIndexes怎么来的?最上边提到过使用编译器注解需要将文件通过建造者传入EventBus中。

 

 

 

上变看到我们在外部通过addIndex加入Builder中,他又把加入的subscriberInfoIndex添加到了subscriberInfoIndexes集合中

,又在EventBus构造中把subscriberInfoIndexes传给了SubscriberMethodFinder,所以我们这里的subscriberInfoIndexes是就有值了。

这里的subscriberInfoIndexes就是我们最上边提到的,也就是我们编译器生成的java文件传入到了eventBus中。

在贴一遍getSubscriberInfo中的方法。

通过index.getSubscriberInfo()就回去到SubscriberInfo了。并返回赋值给findState.subscriberInfo

然后直接从subscriberInfo.getSubscriberMethods获取到SubscriberMethod[]。接下来的就和上篇讲到的流程贯穿了。

就说到这里!!!!

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值