什么是 APT
APT(Annotation Processing Tool)即注解处理器,是一种处理注解的工具.简单来说就是在编译期,根据代码中的注解依据相应的规则生成.java文件.
使用
1.创建 自定义注解
代码语言:javascript复制@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface JetInject {
String value() default "";
}
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface IRouter {
/**
* 该参数当前仅仅支持在activity中使用,表示路由列表
* @return
*/
String[] value() default {};
}
2.创建 java-library类型的 module 作为 compiler
- 自定义 AbstractProcessor,并且用@AutoService注解标记AutoService会自动在META-INF文件夹下生成Processor配置信息文件,该文件里就是注解处理器的全称
com.xxx.appcompiler.compiler.Compiler
自动生成如下文件
代码语言:javascript复制app.compiler/build/classes/java/main/META-INF/services/javax.annotation.processing.Processor
//javax.annotation.processing.Processor 内容如下:
com.xxx.appcompiler.compiler.Compiler
如果不使用 Google 的
代码语言:javascript复制com.google.auto.service:auto-service
这个库,则需要写如下代码:
代码语言:javascript复制1.需要在 processors 库的 main 目录下新建 resources 资源文件夹
2.在 resources文件夹下建立 META-INF/services 目录文件夹
3.在 META-INF/services 目录文件夹下创建 javax.annotation.processing.Processor 文件
4.在 javax.annotation.processing.Processor 文件写入注解处理器的全称,包括包路径
com.xxx.appcompiler.compiler.Compiler
- Compiler类内容
@AutoService(Processor.class)
public class Compiler extends AbstractProcessor {
//process方法会执行多次 这个 flag 用来 保证执行一次
private boolean isFirst;
@Override
public Set<String> getSupportedAnnotationTypes() {
//将我们自定义的注解添加Set集合
Set<String> types = new LinkedHashSet<>();
types.add(JetInject.class.getCanonicalName());
types.add(IRouter.class.getCanonicalName());
types.add(JetInit.class.getCanonicalName());
return types;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
ProcessingManager manager = ProcessingManager.get();
manager.setElementUtils(processingEnv.getElementUtils());
manager.setFiler(processingEnv.getFiler());
manager.setMessager(processingEnv.getMessager());
manager.setTypeUtils(processingEnv.getTypeUtils());
}
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) {
if (isFirst) {
return false;
}
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "---------jet begin --------------------");
isFirst = true;
EleParser.getInstance().initPreCode();
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(JetInject.class);
Set<? extends Element> routers = roundEnv.getElementsAnnotatedWith(IRouter.class);
if (!init(roundEnv)) {
return true;
}
for (Element ele : elements) {
if (ele.getKind() == ElementKind.FIELD) {
EleParser.getInstance().parser(processingEnv, ele, false, true);
} else if (ele.getKind() == ElementKind.CLASS) {
EleParser.getInstance().parser(processingEnv, ele, true, true);
}
}
for (Element ele : routers) {
if (ele.getKind() == ElementKind.CLASS) {
EleParser.getInstance().parser(processingEnv, ele, true, false);
}
}
//使用javapoet生成代码
EleParser.getInstance().build();
return true;
}
}
生成的代码路径
代码语言:javascript复制app/build/generated/source/apt/debug/com/xxx/androidcompileractivity/JetInitializer.java
更多内容 欢迎关注公众号