1.Android注解-编译时生成代码 APT(Annotation Processing Tool ) Poet 说明
2017-08-31 12:10
956 查看
之前了解过这个东西,没深入去研究说明。
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项目,配置如下
代码类也不是很多
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 占位符:
$L代表的是字面量
$S for Strings
$N for Names(我们自己生成的方法名或者变量名等等)
$T for Types
上面的这段代码就是打印我写的这个代码
打印如下:
这个代码,我要说一下: .addStatement(ok,MethodSpec.class,TypeSpec.class,JavaFile.class,System.class)
String ok的占位符是和后面的Type数组是一一对应的,也是相当关键的import相关类,不然容易导致生成的代码不能通过编译,import类导致出现问题,这往往是我们忽略的,自己可以去生成的代码下面去瞅瞅。
AS生成的代码路径如下(debug编译)
如果以前是android-apt写的,可以转annotationProcessor。在android-apt写的代码逻辑一点都不用懂的,直接修改相关配置即可。我在网上找到一篇文档,可以参考一下android-apt切换为annotationProcessor
square/javapoet 源码
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 占位符:
$L代表的是字面量
$S for Strings
$N for Names(我们自己生成的方法名或者变量名等等)
$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编译)
如果以前是android-apt写的,可以转annotationProcessor。在android-apt写的代码逻辑一点都不用懂的,直接修改相关配置即可。我在网上找到一篇文档,可以参考一下android-apt切换为annotationProcessor
square/javapoet 源码
相关文章推荐
- 2.Android注解-编译时生成代码 APT(Annotation Processing Tool ) 实例说明
- Android注解-编译时生成代码 (APT)
- android apt编译时期自动生成代码
- Android APT(编译时代码生成)最佳实践
- apt 根据注解,编译时生成代码
- Android 编译时注解生成代码
- 深入理解编译注解(三)依赖关系 apt/annotationProcessor与Provided的区别
- Java编译时注解自动生成代码
- Android 利用 APT 技术在编译期生成代码
- Android中使用AbstractProcessor在编译时生成代码
- Android 利用 APT 技术在编译期生成代码
- Android注解使用之注解编译android-apt如何切换到annotationProcessor
- Android中利用APT生成代码
- 【Android】打包过程:生成自动代码->编译->(混淆)->dex文件->生成资源文件->打apk包->(签名)->对齐
- Android(Java)编译时注解修改代码
- Android注解使用之注解编译android-apt如何切换到annotationProcessor
- Android 利用 APT 技术在编译期生成代码
- 利用APT实现Android编译时注解
- AndroidAnnotation常用注解使用说明
- 深入理解编译注解(二)annotationProcessor与android-apt