1.Android注解-编译时生成代码 APT(Annotation Processing Tool ) Poet 说明

来源:互联网 发布:西方伦理思想史淘宝 编辑:程序博客网 时间:2024/06/05 09:30

之前了解过这个东西,没深入去研究说明。

Android Gradle插件2.2版本发布后,android 官方提供了annotationProcessor来代替android-apt,annotationProcessor同时支持 javac 和 jack 编译方式,而android-apt只支持 javac 方式。同时android-apt作者宣布不在维护,当然目前android-apt仍然可以正常运行,如果你没有想支持 jack 编译方式的话,可以继续使用 android-apt。

1。首先要学的还是Javapoet,组装生成java元代码的库。看归看,学归学,总之,还是要自己去主动写代码的,不然看了很容易忘记,什么也不懂的。
参考学习地址如下:JavaPoet is a Java API for generating。

我用的 IDEA写的maven Java项目,配置如下

    <dependency>            <groupId>com.squareup</groupId>            <artifactId>javapoet</artifactId>            <version>1.7.0</version>    </dependency>

代码类也不是很多
AnnotationSpec:用来创建注解
ArrayTypeName:用来创建数组[]
ClassName:用来包装一个类
CodeBlock:编写代码块
CodeWriter:
FieldSpec:代表一个成员变量,一个字段声明。
JavaFile:包含一个顶级类的Java文件。
MethodSpec:表一个构造函数或方法声明。
NameAllocator:名称分配器(通过对象得到名字)
ParameterizedTypeName:参数泛型(类List< String> datalist)
ParameterSpec: 用来创建参数
TypeName:如在添加返回值类型是使用
TypeSpec:代表一个类,接口,或者枚举声明
TypeVariableName:泛型
Util:
WildcardTypeName:泛型

就以上这多的类。其中官网也很多参考示例,自己可以尝试写写哦
https://www.programcreek.com/java-api-examples/index.php?api=com.squareup.javawriter.JavaWriter

将上面的api=com.squareup.javawriter.JavaWriter中的api=换成你想看的的类全民,即可差多对应的demo示例。有的没有,大部分类都有的。

POET 占位符:

  1. $L代表的是字面量
  2. $S for Strings
  3. $N for Names(我们自己生成的方法名或者变量名等等)
  4. $T for Types
package com.rulang.poet;import com.rulang.demo.UserBean;import com.squareup.javapoet.*;import javax.lang.model.element.Modifier;import java.io.File;/** * Created by ziyong on 2017/8/30. */public class Test {    public static void main(String[] args) throws Exception{        String ok="$T main = MethodSpec" +                "                .methodBuilder(\"main\") //添加方法的名称\n" +                "                .addModifiers(Modifier.PUBLIC, Modifier.STATIC) //方法修饰的关键字\n" +                "                .addParameter(String[].class, \"args\") //添加方法的参数\n" +                "                .addCode(ok)//添加代码" +                "                .build();\n" +                "        \n" +                "        $T hello = TypeSpec.classBuilder(\"Test\") //添加类的名称\n" +                "                .addModifiers(Modifier.PUBLIC) //添加修饰的关键字\n" +                "                .addMethod(main)  //添加该类中的方法\n" +                "                .build();\n" +                "\n" +                "        String packgeName = Test.class.getPackage().getName(); //生成类的包名\n" +                "        $T file = JavaFile.builder(packgeName, hello).build(); //在控制台输出\n" +                "        file.writeTo($T.out);";        MethodSpec main = MethodSpec                .methodBuilder("main") //添加方法的名称                .addModifiers(Modifier.PUBLIC, Modifier.STATIC) //方法修饰的关键字                .addParameter(String[].class, "args") //添加方法的参数//                .addCode()//添加代码                .addStatement(ok,MethodSpec.class,TypeSpec.class,JavaFile.class,System.class)                .build();        TypeSpec hello = TypeSpec.classBuilder("Test") //添加类的名称                .addModifiers(Modifier.PUBLIC) //添加修饰的关键字                .addMethod(main)  //添加该类中的方法                .build();        String packgeName = Test.class.getPackage().getName(); //生成类的包名        JavaFile file = JavaFile.builder(packgeName, hello).build(); //在控制台输出        file.writeTo(System.out);    }

上面的这段代码就是打印我写的这个代码
打印如下:

package com.rulang.poet;import com.squareup.javapoet.JavaFile;import com.squareup.javapoet.MethodSpec;import com.squareup.javapoet.TypeSpec;import java.lang.Exception;import java.lang.String;import java.lang.System;public class Test {  public static void main(String[] args) throws Exception {    MethodSpec main = MethodSpec                .methodBuilder("main") //添加方法的名称                        .addModifiers(Modifier.PUBLIC, Modifier.STATIC) //方法修饰的关键字                        .addParameter(String[].class, "args") //添加方法的参数                        .addCode(ok)//添加代码                .build();                TypeSpec hello = TypeSpec.classBuilder("Test") //添加类的名称                        .addModifiers(Modifier.PUBLIC) //添加修饰的关键字                        .addMethod(main)  //添加该类中的方法                        .build();                String packgeName = Test.class.getPackage().getName(); //生成类的包名                JavaFile file = JavaFile.builder(packgeName, hello).build(); //在控制台输出                file.writeTo(System.out);;  }}

这个代码,我要说一下: .addStatement(ok,MethodSpec.class,TypeSpec.class,JavaFile.class,System.class)

String ok的占位符是和后面的Type数组是一一对应的,也是相当关键的import相关类,不然容易导致生成的代码不能通过编译,import类导致出现问题,这往往是我们忽略的,自己可以去生成的代码下面去瞅瞅。

AS生成的代码路径如下(debug编译)
我这里是debug路径

如果以前是android-apt写的,可以转annotationProcessor。在android-apt写的代码逻辑一点都不用懂的,直接修改相关配置即可。我在网上找到一篇文档,可以参考一下android-apt切换为annotationProcessor

square/javapoet 源码

阅读全文
0 0
原创粉丝点击