Android開發(fā)中,注解平時我們用的比較多,也許我們會比較好奇辐董,注解的背后是如何工作的,這篇文章幫大家一步步創(chuàng)建一個簡單的注解處理器禀综。
一简烘、創(chuàng)建工程
環(huán)境:AndroidStudio 3.4.2
1、創(chuàng)建項目
打開AndroidStudio定枷,創(chuàng)建一個新的項目AnnotationDemo孤澎,語言選Java,不要勾選androidx支持欠窒。
2覆旭、創(chuàng)建一個新的Java Libray
library名稱填processor
二、創(chuàng)建注解處理器
1岖妄、創(chuàng)建注解類
在processor module下新建一個注解類Greet
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Greet {
String[] value() default "";
}
2型将、對上一步的注解創(chuàng)建注解處理器
在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;
}
}
到這里我們創(chuàng)建了一個注解和一個注解處理器,但是Java虛擬機并不知道如何使用這個注解處理器荐虐,因此我們還需要注冊下這個處理器七兜。
3、注冊注解處理器
在processor/src/main目錄下新建resources文件夾福扬,然后再在resources目錄下新建resources/META-INF和resources/META-INF/services兩個文件夾腕铸,注意,是兩個文件夾忧换。
然后再在resources/META-INF/services目錄下新建javax.annotation.processing.Processor文件恬惯,這個文件名稱請不要拼錯!在這個文件中填寫我們寫好的注解處理器GreetProcessor亚茬,完成后的文件如下:
三酪耳、關聯(lián)processor module到app module
打開app的build.gradle,在dependencies中添加如下代碼:
dependencies {
...
implementation project(':processor')
annotationProcessor project(':processor')
}
四、設置編譯版本
最后需要設置下編譯環(huán)境.
1.在processor module的build.gradle中添加如下代碼
sourceCompatibility = "8"
targetCompatibility = "8"
2.在app module的build.gradle中添加如下代碼
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
四碗暗、測試成果
到這里我們的注解處理器就算完成了颈将,讓我們測試下。
在MainActivity上添加Greet注解
執(zhí)行Build -> rebuild project言疗,我們可以看到build目錄下已經(jīng)生成Greeter類了晴圾,大功告成。
其他
上述項目Greeter類的生成代碼是手寫的噪奄,有很多更加高效的方案可以替代死姚,如Apache Velocity模版、JavaPoet勤篮。這兩種方案在下面項目中有寫都毒,分別在velocity分支和javapoet分支,master分支是手寫的方式碰缔,所以注意切換分支查看账劲。