Android-學習筆記-APT

Scope(作用域)
Qualifier(限定符)

註解

參考一下 兩年前收藏的一篇文章
一小時搞明白自定義註解(Annotation)
注意: 1 如果只有一個參數成員,最好把參數名稱設爲value,當然使用的時候value=也可以省略
2 RetentionPoicy取值,默認是classs 即 @Retention(RetentionPolicy.CLASS)

Java註解Annotation詳解

APT概念

APT(Annotation Processing Tool)即註解處理器。
APT 是一種處理註解的工具,在編譯期,通過註解生成.java文件。

使用

1 java module 引用的jar:

    api 'com.google.auto.service:auto-service:1.0-rc4'

    //開源java代碼生成框架
    api 'com.squareup:javapoet:1.10.0'

2 processor
側重點是 javapoet常用api
1 佔位符
$L 代表的是字變量
$S for Strings(字符串)
$N for Names(我們自己生成的方法名或者變量名等等)
$T for Types (類.class,接口,枚舉)

// 註冊
@AutoService(Processor.class)
//當前註解處理器 能夠處理的註解 代替 getSupportedAnnotationTypes 方法
@SupportedAnnotationTypes({"package.annotation.TestAnnotation"})
//java 版本,代替getSupportedSourceVersion
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class TestProcessor extends AbstractProcessor {

    //日誌輸出類
    private Messager messager;
    private Filer filer;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {···}
       
    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        for (TypeElement typeElement : set) {
            messager.printMessage(Diagnostic.Kind.NOTE, "charSequence---------" + roundEnvironment.getElementsAnnotatedWith(typeElement));
            createJava();
        }
        return true;
    }

//    TypeSpec是類/接口/枚舉的抽象,
//    MethodSpec是方法/構造函數的抽象,
//    FieldSpec是成員變量/字段的抽象。
    private void createJava() {
        //1 創建 成員變量
        FieldSpec fieldSpec =  FieldSpec.builder(String.class ,"name",Modifier.PRIVATE).build();

        //2.1 創建方法
        // addModifiers 對方法的修飾約束,
        // addParameter 添加方法參數 ,
        // addStatement 方法體,
        // returns 返回值
        MethodSpec method = MethodSpec.methodBuilder("test")
                .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                .returns(void.class)
                .addStatement("$T.out.println($S)", System.class, "hello")
                .addStatement("$T.out.println($S)", System.class, "wrold")
                .build();

        //2.2 addCode
        MethodSpec method2 = MethodSpec.methodBuilder("test2")
                .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                .addCode(""
                        +  "System.out.println("+"\"hello\""+");\n"
                        +  "System.out.println("+"\"world\""+");\n"
                        )
                .build();


        //2.3 創建 構造方法
        MethodSpec constructor =   MethodSpec.constructorBuilder()
                .addModifiers(Modifier.PUBLIC)
                .addParameter(String.class,"name")
                .addStatement("this.$N = $N", "name", "name")
                .build();

        //創建 匿名類
        TypeSpec comparator = TypeSpec.anonymousClassBuilder("")
                .addSuperinterface(ParameterizedTypeName.get(Comparator.class, String.class))
                .addMethod(MethodSpec.methodBuilder("compare")
                        .addAnnotation(Override.class)
                        .addModifiers(Modifier.PUBLIC)
                        .addParameter(String.class, "a")
                        .addParameter(String.class, "b")
                        .returns(int.class)
                        .addStatement("return $N.length() - $N.length()", "a", "b")
                        .build())
                .build();


        //3 創建類
        TypeSpec clazz = TypeSpec.classBuilder("HelloWorld")
                .addModifiers(Modifier.PUBLIC,Modifier.FINAL)
                .addField(fieldSpec)

                .addMethod(constructor)
                .addMethod(method)
                .addMethod(method2)
                .addMethod(MethodSpec.methodBuilder("sortByLength")
                        .addModifiers(Modifier.PUBLIC,Modifier.STATIC)
                        .addParameter(ParameterizedTypeName.get(List.class, String.class), "strings")
                        .addStatement("$T.sort($N, $L)", Collections.class, "strings", comparator)
                        .build())
                .build();

		//4  創建 Java文件
        JavaFile javaFile = JavaFile.builder("package.hello", clazz).build();
        //輸出文件
        try {
            javaFile.writeTo(filer);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

3 引用
使用註解 如 @TestAnnotation(“main”)
編譯成功後 使用註解生成代碼增加的功能。

參考
java註解與APT技術述
兩個例子:
Android 中的Apt基本使用

【Android】APT

Javapoet api 重點
Android關於AutoService、Javapoet講解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章