参考:http://www.matools.com/api/java8
旨在用作最具体注释 processor 的便捷超类的抽象注释 processor。此类检查注释值,以计算其子类型所支持的选项、注释和源版本。
在 processor 被初始化之后,获取方法可以使用可用设施来发出有关值得注意的条件的警告。
只要遵守该方法的常规 Processor 协定,子类可随意重写此类中任何方法的实现和规范。
init:用处理环境初始化 processor,方法是将 processingEnv 字段设置为 processingEnv 参数的值。如果在同一对象上多次调用此方法,则抛出 IllegalStateException。参数:processingEnv - 用来访问工具框架提供给 processor 的设施的环境
getSupportedOptions:如果 processor 类是使用 SupportedOptions 注释的,则返回一个不可修改的集合,该集合具有与注释相同的字符串集。如果类不是以这种方式注释的,则返回一个空集合。
getSupportedAnnotationTypes:返回支持注释类型名称的set集合
getSupportedSourceVersion:返回注释中的源版本。
process:处理先前 round 产生的类型元素上的注释类型集,并返回这些注释是否由此 Processor 声明。如果返回 true,则这些注释已声明并且不要求后续 Processor 处理它们;如果返回 false,则这些注释未声明并且可能要求后续 Processor 处理它们。Processor 可能总是返回相同的 boolean 值,或者可能基于所选择的标准而返回不同的结果。
如果 Processor 支持 “*” 并且根元素没有注释,则输入集合将为空。Processor 必须妥善处理空注释集。
参数:annotations - 请求处理的注释类型;roundEnv - 有关当前和以前 round 的信息的环境
返回:注释集是否由此 Processor 声明
getCompletions:返回一个空的 completion 迭代。
参数:
element - 将被注释的元素
annotation - 将应用于元素的注释(可能是一部分)
member - 为其返回可能 completion 的注释成员
userText - 将补充完整的源代码文本
isInitialized
如果此对象已被 初始化,则返回 true,否则返回 false。
参考:http://tool.oschina.net/apidocs/apidoc?api=jdk-zh
注释处理工具框架将提供一个具有实现此接口的对象的注释 processor,因此 processor 可以使用该框架提供的设施来编写新文件、报告错误消息并查找其他实用工具。
第三方可能希望提供能包装此接口设施对象的增值包装器,例如,允许多个 processor 协同写出单个源文件的 Filer 扩展。为了实现这一点,对于在其副作用可通过 API 相互可见的上下文中运行的 processor,工具基础设施必须提供相应的设施对象,这些对象是 .equals、作为 .equals 的 Filer 等等。此外,必须能够配置工具调用,使得从运行注释 processor 的角度来看,至少已选定的帮助 (helper) 类子集可视为由相同的类加载器加载。(因为设施对象管理共享状态,所以包装器类的实现必须知道以前是否包装过相同的基本设施对象。)
getOptions():返回传递给注释处理工具的特定于 processor 的选项。选项是以从选项名称到选项值的映射形式返回的。对于不包含任何值的选项,映射中的对应值为 null。
关于如何传入特定于 processor 的选项的详细信息,请参阅特定工具基础设施的文档。例如,命令行实现可以通过使用已知字符串作为特定于 processor 的选项的前缀来区分它们;其他工具实现可能遵守不同的约定或提供替换机制。除了特定于 processor 的选项外,给定实现还可以提供特定于实现的方式来查找传递给该工具的选项。
返回:传递给工具的特定于 processor 的选项
getMessager()
返回用来报告错误、警报和其他通知的 Messager。
返回:Messager
getFiler()
返回用来创建新源、类或辅助文件的 Filer。
返回:Filer
getElementUtils()
返回用来在元素上进行操作的某些实用工具方法的实现。
返回:元素实用工具
getTypeUtils()
返回用来在类型上进行操作的某些实用工具方法的实现。
返回:类型实用工具
getSourceVersion()
返回任何生成的 源和 类文件应该符合的源版本。
返回:生成的源和类文件应该符合的源版本
getLocale()
返回当前语言环境;如果没有有效的语言环境,则返回 null。该语言环境可用来提供本地化的 消息。
返回:当前语言环境;如果没有有效的语言环境,则返回 null
刚接触Annotation Processor的同学可能会遇到找不到AbstractProcessor类的问题,大概率是因为直接在Android项目里边引用了AbstractProcessor,然而由于Android平台是基于OpenJDK的,而OpenJDK中不包含Annotation Processor的相关代码。因此,在使用Annotation Processor时,必须在新建Module时选择Java Library,处理注解相关的代码都需要在Java Library模块下完成。我们需要看一下整个项目的结构
新建两个 Java Library,在新建Module时选择下图:
名称分别为router_annotation和router_compiler(注解处理器),如下图:
在router_compiler中添加router_annotation为依赖库,如下图:
查看router_compiler的build.gradle文件,如下图:
在router_annotation中添加注解:
//添加元注解
// @Target(ElementType.TYPE) //接口、类、枚举、注解
// @Target(ElementType.FIELD) //字段、枚举的常量
// @Target(ElementType.METHOD) //方法
// @Target(ElementType.PARAMETER) //方法参数
// @Target(ElementType.CONSTRUCTOR) //构造函数
// @Target(ElementType.LOCAL_VARIABLE)//局部变量
// @Target(ElementType.ANNOTATION_TYPE)//注解
// @Target(ElementType.PACKAGE) ///包
@Target(ElementType.TYPE)
//注解的生命周期
//RetentionPolicy.SOURCE 源码阶段
//RetentionPolicy.CLASS 编译阶段
//RetentionPolicy.RUNTIME 运行阶段
@Retention(RetentionPolicy.CLASS)
public @interface Route {
/**
*路由的路径,标识一个路由节点
*/
String path();//没有默认值
/**
* 将路由节点进行分组,可以实现按组动态加载
*/
String group() default "";//有默认值
}
因为String path()没有设置默认值,所有在使用Route注解的时候必须设置path的值。
@Target({
ElementType.FIELD})
@Retention(RetentionPolicy.CLASS)
public @interface Extra {
String name() default "";
}
app中添加router_annotation依赖。
在MainActivity添加注解:
@Route(path="/main/mainactivity")//1
public class MainActivity extends AppCompatActivity {
@Extra(name="path")
private String path;
}
注释1:在Route中path没有默认值,所以必须设置path。
在router_compiler中:
在router_compiler中新建自定义注解处理器RouteProcessor:
public class RouteProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
return false;
}
}
在这个类上添加了@AutoService注解,它的作用是用来生成META-INF/services/javax.annotation.processing.Processor文件的,也就是我们在使用注解处理器的时候需要手动添加META-INF/services/javax.annotation.processing.Processor,而有了@AutoService后它会自动帮我们生成。AutoService是Google开发的一个库,使用时需要在 factory-compiler中添加依赖。
在router_compiler的build.gradle中添加依赖,如下:
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc6'
compileOnly 'com.google.auto.service:auto-service:1.0-rc6'
在RouteProcessor中注册注解处理器:
/**
* 在这个类上添加了@AutoService注解,它的作用是用来生成
* META-INF/services/javax.annotation.processing.Processor文件的,
* 也就是我们在使用注解处理器的时候需要手动添加
* META-INF/services/javax.annotation.processing.Processor,
* 而有了@AutoService后它会自动帮我们生成。
* AutoService是Google开发的一个库,使用时需要在
* factory-compiler中添加依赖
*/
@AutoService(Processor.class) //注册注解处理器
public class RouteProcessor extends AbstractProcessor {
}
Make Project后查看生产的文件,如下图:
打开查看如下:
自动生成了RouteProcessor的路径。
在RouteProcessor中覆写3个方法,如下:
@AutoService(Processor.class) //注册注解处理器
public class RouteProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
return false;
}
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.RELEASE_7;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return super.getSupportedAnnotationTypes();
}
}
这里也可以通过注解的方式实现,如下:
@AutoService(Processor.class) //注册注解处理器
@SupportedOptions("moduleName")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
@SupportedAnnotationTypes({
"com.hongx.router_annotation.Route"})
public class RouteProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
return false;
}
}
Android注解处理器(APT)简单实例
在上面使用了StringBuilder来构建类的,比较麻烦,我们可以使用javapoet简化构建类过程。
javapoet