Android apt学习记录

AbstractProcessor 注解处理器

javac的一个工具,用来在编译时扫描和编译和处理注解(Annotation)的。只能生成新文件。

  • ProcessingEnvironment

    提供 Element,Filer,Messager等工具,Filer在生成java文件使用,Messager可以打印日志,调试时使用的最多。 (Messager日志在Android studio - Build - Toggle View面板查看)

  • getSupportedAnnotationTypes() 指定当前处理器可以处理的注解

  • getSupportedSourceVersion() 指定java版本

  • process () 正真处理注解逻辑的地方

	@Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {

        if (set.isEmpty()) {

            mMessager.printMessage(Diagnostic.Kind.WARNING, DialogAnnotation.class.getSimpleName() + " is not used");
            return false;
        }
 
        //1、获取注解处理器标记的所有元素
        Set<? extends Element> elementsAnnotatedWith = roundEnvironment.getElementsAnnotatedWith(DialogAnnotation.class);
        //2、遍历元素,拿到注解值
        for (Element element : elementsAnnotatedWith) {
			//3、判断元素类型是否是欲处理的类,element.asType()可以拿到具体类型
            if (!element.getKind().isClass()) {

                continue;
            }
			
            String clazzName = element.toString();

            //4、获取元素上所有注解
            List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors();
            for (AnnotationMirror mirror : annotationMirrors) {
 
                //获取元素值
                Set<? extends Map.Entry<? extends ExecutableElement, ? extends AnnotationValue>> entrySet = mirror.getElementValues().entrySet();
				//5、遍历注解上的每个键值对
                for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : entrySet) {
					//键
                    Name key = entry.getKey().getSimpleName();
					//值
                    String value = entry.getValue().toString();
                     ...处理过程...
                }

     			//打印日志
                mMessager.printMessage(Diagnostic.Kind.NOTE, "日志信息");
            }
        }
		
		//6、根据处理过程中的到的数据生成java文件
        createJavaFile(xxx);
        return true;

    }

JavaPoet

一个用来生成java文件的第三方库

MethodSpec

代表一个构造函数或方法声明
TypeSpec

代表一个类,接口,或者枚举声明

FieldSpec

代表一个成员变量,一个字段声明

JavaFile

包含一个顶级类的Java文件

ParameterSpec
用来创建参数

AnnotationSpec
用来创建注解

ClassName
表示一个类,如Activity类为:
ClassName activityClassName = ClassName.get("android.app", "Activity");

TypeName
表示类型

占位符

$L 字面量 用于拼接字符串,不会添加""
$S 字符串 会在值前后加""
$T 类、接口
$N 变量

github例子

package com.example.helloworld;

public final class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, JavaPoet!");
  }
}

// And this is the (exciting) code to generate it with JavaPoet:

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") //定义一个类,名为HelloWorld
    .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
    .addMethod(main)   //添加方法,可以调用多次
    .build();

JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
    .build(); //指定包名,生成java文件

javaFile.writeTo(System.out);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值