Android开发中,注解平时我们用的比较多,也许我们会比较好奇,注解的背后是如何工作的,这篇文章帮大家一步步创建一个简单的注解处理器。
一、创建工程
环境:AndroidStudio 3.4.2
1、创建项目
打开AndroidStudio,创建一个新的项目AnnotationDemo,语言选Java,不要勾选androidx支持。
2、创建一个新的Java Libray
创建Modue.png选择JavaLibray.png
library名称填processor
image.png
二、创建注解处理器
1、创建注解类
在processor module下新建一个注解类Greet
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Greet {
String[] value() default "";
}
image.png
2、对上一步的注解创建注解处理器
在processor module下新建一个注解处理器类GreetProcessor
// 这里填写要处理的注解类
@SupportedAnnotationTypes("xh.destiny.processor.Greet")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class GreetProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) {
// 1.获取类型信息
Collection<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(Greet.class);
List<TypeElement> types = ElementFilter.typesIn(annotatedElements);
String packageName = null;
String[] names = null;
for (TypeElement type : types) {
PackageElement packageElement = (PackageElement) type.getEnclosingElement();
packageName = packageElement.getQualifiedName().toString();
names = type.getAnnotation(Greet.class).value();
}
if (packageName == null) return false;
// 2.构造Java代码
StringBuilder builder = new StringBuilder()
.append("package " + packageName + ";\n\n")
.append("public class Greeter {\n\n")
.append(" public static String hello() {\n")
.append(" return \"Hello ");
for (int i = 0; i < names.length; i++) {
if (i == 0) {
builder.append(names[i]);
} else {
builder.append(", ").append(names[i]);
}
}
builder.append("!\";\n")
.append(" }\n")
.append("}\n");
// 3.生成Java源文件
try {
JavaFileObject javaFileObject = processingEnv.getFiler().createSourceFile(packageName + ".Greeter");
Writer writer = javaFileObject.openWriter();
writer.write(builder.toString());
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}
image.png
到这里我们创建了一个注解和一个注解处理器,但是Java虚拟机并不知道如何使用这个注解处理器,因此我们还需要注册下这个处理器。
3、注册注解处理器
在processor/src/main目录下新建resources文件夹,然后再在resources目录下新建resources/META-INF和resources/META-INF/services两个文件夹,注意,是两个文件夹。
然后再在resources/META-INF/services目录下新建javax.annotation.processing.Processor文件,这个文件名称请不要拼错!在这个文件中填写我们写好的注解处理器GreetProcessor,完成后的文件如下:
三、关联processor module到app module
打开app的build.gradle,在dependencies中添加如下代码:
dependencies {
...
implementation project(':processor')
annotationProcessor project(':processor')
}
image.png
四、设置编译版本
最后需要设置下编译环境.
1.在processor module的build.gradle中添加如下代码
sourceCompatibility = "8"
targetCompatibility = "8"
image.png
2.在app module的build.gradle中添加如下代码
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
image.png
四、测试成果
到这里我们的注解处理器就算完成了,让我们测试下。
在MainActivity上添加Greet注解
image.png
执行Build -> rebuild project,我们可以看到build目录下已经生成Greeter类了,大功告成。
image.png
其他
上述项目Greeter类的生成代码是手写的,有很多更加高效的方案可以替代,如Apache Velocity模版、JavaPoet。这两种方案在下面项目中有写,分别在velocity分支和javapoet分支,master分支是手写的方式,所以注意切换分支查看。
网友评论