APT 编译时注解 知识点

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:表示某个类或接口的方法、构造方法或初始化程序(静态或实例),包括注释类型元素。

你可能感兴趣的:(APT 编译时注解 知识点)