上篇我们详细介绍了注解,相信你已经对注解有了大概的了解,以及它可以给我们带来什么帮助,这篇文章我们继续实现 Extra 中的需求,我们已经定义好了注解,那我们怎么根据定义的注解帮我们自动生成获取数据的代码呢,这就是我们今天要讲得注解解析器。
先看下我们上篇文章定义的注解
自定义注解处理器
我们需要自定义一个注解处理类来处理我们注解,需继承自AbstractProcessor
每个方法我都写了注释,这里需要补充一下的是
getSupportedAnnotationTypes()和getSupportedSourceVersion()我们也可以通过注解申明
123456(Processor.class)"me.loody.extra.annotation.ExtraParam")((SourceVersion.RELEASE_7)public final class ExtraParamProcessor extends AbstractProcessor {}@AutoService 是为了向javac注册我们这个自定义的注解处理器,这样,在javac编译时,才会调用到我们这个自定义的注解处理器方法。AutoService这里主要是用来生成META-INF/services/javax.annotation.processing.Processor文件的。如果不加上这个注解,那么,你需要自己进行手动配置进行注册,目录结构如下图
javax.annotation.processing.Processor中定义至自定义注解处理类的路径即可
1me.loody.extra.compiler.ExtraParamProcessor
注解处理器(APT)语法
这里我推荐一篇文章Android编译时注解框架-语法讲解,对APT语法做了详细的解释。这里我整理了下Element子类方法如下
Element 子类 | 含义 | 对应Target |
---|---|---|
ExecutableElement | 表示某个类或接口的方法、构造方法或初始化程序(静态或实例),包括注释类型元素。 | @Target(ElementType.METHOD) @Target(ElementType.CONSTRUCTOR) |
PackageElement | 表示一个包程序元素。提供对有关包极其成员的信息访问。 | @Target(ElementType.PACKAGE) |
TypeElement | 表示一个类或接口程序元素。提供对有关类型极其成员的信息访问 | @Target(ElementType.TYPE) |
TypeParameterElement | 表示一般类、接口、方法或构造方法元素的类型参数。 | @Target(ElementType.PARAMETER) |
VariableElement | 表示一个字段、enum常量、方法或构造方法参数、局部变量或异常参数。 | @Target(ElementType.LOCAL_VARIABLE) |
语法了解了,接下来只需要实现就好了,这里我主要说下思路
- 通过注解处理器解析出我们申明的变量,主要是类型,变量名
- 通过javapoet生成java代码,javapoet语法这里不做介绍,大家自行了解。
具体代码我已经上传到github,见ExtraParamProcessor