根据注解,创建代码的简单例子
根据注解,创建代码的简单例子
关于注解然后调用继承于AbstractProcessor类,可以做到编译时期插入新的代码。类似我们要求电脑在编译的时候顺便写下代码。(APT生成代码技术)感觉是AOP,面向切面编程。
AbstractProcessor类是帮助我们写代码的一个类。
首先写一个简单的例子
1、创建javaLib Module项目
创建一个Android 项目,在项目中创建一个javaLib Module 项目,起个名字叫AutoCode吧,自动代码的意思。
- 添加AutoCode需要的代码库
在AtuoCode 的build.gradle 中添加
dependencies{
...............
// 谷歌写的 用于编译的时候 会帮助生成代码 执行到
compile 'com.google.auto.service:auto-service:1.0-rc2'
//一个开源库,大佬封装的方法
compile 'com.squareup:javapoet:1.7.0'
}
以上AutoCode 的配置就完成了
2. 编写注解
现在写一个注解,就BindView 吧,我想自己写个注解来帮忙findViewById,写过反射的,但是效率低,想试试AOP。
@Target(ElementType.FIELD) //注解用于变量
@Retention(RetentionPolicy.CLASS)//编译的时候只会留下class文件
public @interface BindView {
int value();
}
写完注解,就可以写注解解释器了。注解只是一个标签,我们需要一个解释器在编译的时候发现有 这些标签的对象 来进行操作。
3.编写注解 解释器
创建一个继承AbstractProcessor的类,叫MyClass类吧。
这个类在编译的时候不会自动执行,但是刚刚上面导入了谷歌的库:
compile 'com.google.auto.service:auto-service:1.0-rc2'
所以可以使用一个@AutoService注解,编译期间会自动执行到。
跟下面一样:
@AutoService(Processor.class)
public class MyClass extends AbstractProcessor {
.......
}
AbstractProcessor 类中,需要实现4个方法
init : 初始化操作
getSupportedAnnotationTypes :绑定注解类
getSupportedSourceVersion :确定使用的JDK版本
process :帮我们创建代码的操作都在这里完成
以下我贴代码:
@AutoService(Processor.class)
public class MyClass extends AbstractProcessor {
{
/**
* 文件相关的辅助类
*/
private Filer mFiler;
/**
* 元素相关的辅助类
*/
private Elements mElementUtils;
/**
* 日志相关的辅助类
*/
private Messager mMessager;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
mFiler = processingEnv.getFiler();
mElementUtils = processingEnv.getElementUtils();
mMessager = processingEnv.getMessager();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
TypeSpec myCodeClass = TypeSpec.classBuilder("MyCodeClass")
.addModifiers(Modifier.PUBLIC)
.build();
JavaFile javaFile = JavaFile
.builder("com.example.alex",
myCodeClass)
.build();
try {
javaFile.writeTo(mFiler);
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
//绑定注解,对添加过绑定注解的变量进行操作
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> strings = new LinkedHashSet<>();
strings.add(Override.class.getCanonicalName());
strings.add(BindView.class.getCanonicalName());
return strings;
}
//判定使用的jdk版本
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.RELEASE_7;
}
}
最后还要把javaLib Module添加到android 依赖中去
主模块APP下的build.gradle 文件添加配置
defaultConfig{
.....
//Process 可能会出异常,需要添加这条。
javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
}
dependencies{
......
//添加导入JavaLib包,因为有些类只有在java项目中才拥有
implementation project(':AutoCode')
}
使用:直接在变量上使用注解就可以了
@BindView(R.id.textView)
private TextView mTextView;
效果图:
总结:
1、创建JavaLib Module
添加配置、注解、注解解释器
2、主项目添加javaLib 依赖
3、使用注解