APT的作用
可以在编译时生成额外的.java文件,在程序运行的时候调用相关方法,可以达到减少重复代码的效果。
注解处理器(AbstractProcess) + 代码处理(javaPoet) + 处理器注册 (AutoService) + APT
原理
通过APT(Annotation Processing Tool)技术,即注解处理器,在编译时扫描并处理注解,注解处理器最终生成处理注解逻辑的.java文件。
实现方案
步骤一:创建自定义注解
创建一个Java Library,名称为annotation,作用是保存所有注解。
步骤二:实现注解处理器AbstractProcessor
创建一个Java Library,名称为processor,作用是扫描、解析、处理注解。
::processor
的Gradle配置如下:
apply plugin: 'java-library'
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation project(':annotation')
//用于自动为 JAVA Processor 生成 META-INF 信息。
implementation 'com.google.auto.service:auto-service:1.0-rc7'
//快速生成.java文件的库
implementation 'com.squareup:javapoet:1.13.0'
}
Q1:注解处理器processor为什么要在META-INF注册?
在编译时,java编译器(javac)会去META-INF中查找实现了的AbstractProcessor的子类,并且调用该类的process函数,最终生成.java文件。其实就像activity需要注册一样,就是要到META-INF注册 ,javac才知道要给你调用哪个类来处理注解。
Q2:注解处理器processor是如何被系统调用的?
4134622-55d88199566ac011.png首先,APT是javac提供的一种工具,它在编译时扫描、解析、处理注解。它会对源代码文件进行检测,找出用户自定义的注解,根据注解、注解处理器和相应的apt工具自动生成代码。这段代码是根据用户编写的注解处理逻辑去生成的。最终将生成的新的源文件与原来的源文件共同编译(注意:APT并不能对源文件进行修改操作,只能生成新的文件,例如往原来的类中添加方法)。
注解申明和注解处理器为什么要分Module处理?
我们都知道注解处理器都需要继承AbstractProcessor类,但是AbstractProcessor是JDK中的类,不在android sdk中,所以需要放在单独的java lib中;而processor中需要依赖自定义注解,把annotation抽成一个独立的lib,便于维护。
那注解声明和注解处理为什么要分开呢?可不可以放在一起?
先说结论:可以放在一起,放在一起对功能上没有什么影响;但是一般不放在一起,原因如下:
我们都知道processor的作用是:在编译器解析注解、生成新的.java文件。这个lib只在编译器用到,是不会被打包进apk的。对于调用者来说,你只是想使用这个注解,而不希望你已经编译好的项目中引进注解处理器相关的内容,所以为了不引入没必要的文件,我们一般选择将注解声明和注解处理分开处理。
代理类的位置如下:app-->build-->generated-->source-->apt-->debug
感谢:
网友评论