在上一篇研究了EventBus源码时,默认情况下EventBus是通过在运行时反射的方式去获取订阅者中所有@Subscribe注解的方法信息,这种方式是比较损耗性能的。
EventBus是如何提升效率?
与Butterknife类似,采用编译时注解,在项目编译时将所有的订阅者注解的方法集中到生成class文件中,通过这种方式有效的避免了反射获取注解类的方法信息带来的性能损耗。
基本使用
在项目中集成apt插件
1 | android { |
先Make Project,apt插件会帮我们生成CustomEventBusIndex
1 | public class CustomEventBusIndex implements SubscriberInfoIndex { |
EventBus自定义初始化
1 | public class MyApplication extends Application { |
通过APT插件获取所有订阅者注解信息放入生成class类中,避免运行时反射带来的性能损耗了。
插件源码分析
- 首先分析EventBusAnnotationProcessor#process ()
1 | /** |
主要通过分析添加订阅者,过滤非法订阅者或方法,生成java文件这三个步骤
- 分析1 collectSubscribers()
1 | private void collectSubscribers(Set<? extends TypeElement> annotations, RoundEnvironment env, Messager messager) { |
checkHasNoErrors() 过滤static、非public、无参的方法
1 | private boolean checkHasNoErrors(ExecutableElement element, Messager messager) { |
- 分析2 checkForSubscribersToSkip(),如果订阅者 类与方法都是不可见的 添加至过滤classesToSkip集合,后续进行过滤
1 | private void checkForSubscribersToSkip(Messager messager, String myPackage) { |
上面有一个isVisible(),用于判断元素的修饰符
1 | private boolean isVisible(String myPackage, TypeElement typeElement) { |
- 分析3 createInfoIndex(index),java文件生成
1 | private void createInfoIndexFile(String index) { |
让我们看看writeIndexLines(writer, myPackage)到底做了什么操作
1 | private void writeIndexLines(BufferedWriter writer, String myPackage) throws IOException { |
很明显就是集合的遍历写入,其中包括过滤不合适的订阅者及方法。
到这里EventBusAnnotationProcessor类就分析完成了,接下来打算写一篇自定义ButterKnife文章,深刻学习自定义AbstractProcessor。
感谢观看。