美文网首页
Android Annotation Processor

Android Annotation Processor

作者: 贪无忧 | 来源:发表于2019-08-11 01:20 被阅读0次

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,完成后的文件如下:

image.png

三、关联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分支是手写的方式,所以注意切换分支查看。

项目Demo地址

参考文章

美女教写自定义注解处理器part1

美女教写自定义注解处理器part2

相关文章

网友评论

      本文标题:Android Annotation Processor

      本文链接:https://www.haomeiwen.com/subject/hatjjctx.html