android 自定义注解处理器

作用:

       注解处理器就是将注解生成对应的java类,生成java类可以使用javaPoet。

如何自定义注解处理器呢?有以下步骤:

1、我们创建一个module,名字为testProcessor,注意它是一个java library;如果是一个java library,在testProcessorx下的build.gradle中第一行是apply plugin: 'java-library',但是这个插件只有在gradle 4才支持,修改方式:file--->project structure--->Project---->gradle version 将版本改成4.1

2、创建一个注解类,这个类必须继承自AbstractProcessor,如下所示:

public class TestProcessor extends AbstractProcessor 

其实注解类和我们的Activity一样也需要注册,但是我们可以使用google自带的工具auto-service,testProcessor中的build.gradle代码如下:

apply plugin: 'java-library' //引入的插件,需要将gradle版本修改到4以上

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.google.auto.service:auto-service:1.0-rc2' //引入auto-service实现注解自动注册
    implementation 'com.squareup:javapoet:1.7.0' //使用开源框架javapoet生成Java类
}

sourceCompatibility = "1.7" //指定java兼容版本
targetCompatibility = "1.7"

同时我们需要注解类上添加一些注解,代码如下:

@AutoService(Processor.class) //使用此注解自动注册,
//当前注解处理器能够处理的注解 代替 getSupportedAnnotationTypes函数
@SupportedAnnotationTypes({"com.example.administrator.apt.Route"})//定义注解处理器需要处理注解的类型
//java版本 代替 getSupportedAnnotationTypes 函数
@SupportedSourceVersion(SourceVersion.RELEASE_7) //指定jdk的版本
public class TestProcessor extends AbstractProcessor {
android 自定义注解处理器_第1张图片

这就是注解器注册的位置,然后文件中的内容就是我们注解器的全类名,如com.example.testprocessor.TestProcessor

然后在app中的build.gradle中引用此注解:

annotationProcessor project(':testProcessor')

3、重写注解器的init方法和process方法,代码如下:

/**
 * Created by Administrator on 2018/3/21.
 */

@AutoService(Processor.class)
//当前注解处理器能够处理的注解 代替 getSupportedAnnotationTypes函数
@SupportedAnnotationTypes({"com.example.administrator.apt.Route"})
//java版本 代替 getSupportedAnnotationTypes 函数
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class TestProcessor extends AbstractProcessor {


    private Messager messager;
    Filer filer;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        filer = processingEnvironment.getFiler();
        messager = processingEnvironment.getMessager();//获取信息打印工具
        messager.printMessage(Diagnostic.Kind.NOTE, "TestProcessor=============init");//打印信息,在Gradle Console可以看到打印信息,如果第一个参数写成Kind.ERROR将会信息中断
    }

    @Override
    public boolean process(Set set, RoundEnvironment roundEnvironment) {
        messager.printMessage(Diagnostic.Kind.NOTE, "TestProcessor=============process");
        for (TypeElement typeElement : set) {//set集合都是注解节点,但是我们要拿到的是被注解的节点
            MethodSpec main = MethodSpec.methodBuilder("main")//创建方法
                    .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                    .returns(void.class)
                    .addParameter(String[].class, "args")
                    .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
                    .build();

            TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")//创建类
                    .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                    .addMethod(main)
                    .build();

            JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
                    .build();//创建文件

            try {
                javaFile.writeTo(filer);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
}

以上process方法中的for中的作用就是生成java类,java文件,此文件存放app--build---generated---source--apt如下所示;

android 自定义注解处理器_第2张图片

4、如果需要传递参数,我们可以在app的build.gradle中的defaultConfig中配置一下代码:

 javaCompileOptions {
            annotationProcessorOptions {
                arguments = [moduleName: project.getName()]
            }
        }

同时在TestlProcessor之上添加一个注解

/**
 * 处理器接收的参数 替代 {@link AbstractProcessor#getSupportedOptions()} 函数
 */
@SupportedOptions("moduleName")

你可能感兴趣的:(Android,Java)