1. 怎么自定义编译时注解的名称(以我的项目 AutoInject 为例)
-
第一种方法:
在AutoInject-compiler的main目录下创建目录resources/META-INF/services,并在该目录下创建文件javax.annotation.processing.Processor,在该文件中写入注解处理器的全限定类名(这里是com.zilong.compiler.AutoInjectProcessor) -
第二种方法:
特别简单,只需要导入依赖google提供的auto-service开源库。如下:apply plugin: 'java-library' dependencies { implementation project(':annotation') implementation fileTree(dir: 'libs', include: ['*.jar']) //************************************************************** implementation 'com.google.auto.service:auto-service:1.0-rc4' //这里是导入的google开源库 //************************************************************* implementation 'com.squareup:javapoet:1.11.1' } sourceCompatibility = "8" targetCompatibility = "8"
然后在注解处理器上添加注解@AutoService(Processor.class)即可。如下:
@AutoService(Processor.class) @SupportedSourceVersion(SourceVersion.RELEASE_8) public class AutoInjectProcessor extends AbstractProcessor { ... }
2. 为什么一般都分为两个库(***-compiler 和 ***-annotation)
因为自定义AbstractProcessor的作用是在编译时生成相关的java源文件的,在程序中最后需要的是他生成的Java文件,最后打包进apk也是他生成的文件,***-compiler 本身是不需要打包的。 但是在 ***-compiler和主工程(用到编译时注解的业务代码工程)中需要对具体的注解类进行操作,所以将具体的注解Annotation放在一个库 ***-annotations中便于引用。
3. 为什么***-compiler工程要建成 java工程
在使用自定义AbstractProcessor需要使用到 javax 包中的相关类和接口,这个在android库中并不存在,所以需要使用到Java库。
4. Element 接口 参数解释
#获取类名
Element.getSimpleName().toString();
#获取类的全名
Element.asType().toString();
#获取所在的包名
Elements.getPackageOf(Element).asType().toString();
#获取所在的类
Element.getEnclosingElement();
#获取父类
Types.directSupertypes(Element.asType());
#获取标注对象的类型
Element.getKind();
Elment有几个子接口如下:他们的特有方法,用到了自己查一下
TypeElement:表示一个类或接口程序元素。
PackageElement:表示一个包程序元素。
VariableElement:表示一个属性、enum 常量、方法或构造方法参数、局部变量或异常参数。
ExecutableElement:表示某个类或接口的方法、构造方法或初始化程序(静态或实例),包括注释类型元素。
网友评论