apt:

@Retention后面的值,设置的为CLASS,说明就是编译时动态处理的。一般这类注解会在编译的时候,根据注解标识,动态生成一些类或者生成一些xml都可以,在运行时期,这类注解是没有的~~会依靠动态生成的类做一些操作,因为没有反射,效率和直接调用方法没什么区别~~~

RUNTIME, 说明就是运行时动态处理,这个大家见得应该最多,在运行时拿到类的Class对象,然后遍历其方法、变量,判断有无注解声明,然后做一些事情。

SOURCE,标记一些信息,这么说可能太抽象,那么我说,你见过@Override、@SuppressWarnings等,这类注解就是用于标识,可以用作一些检验 

 

@Target表示该注解可以用于什么地方,可能的类型TYPE(类),FIELD(成员变量)

 1 public enum ElementType {  
 2     /** 
 3      * Class, interface or enum declaration. 
 4      */  
 5     TYPE,  
 6     /** 
 7      * Field declaration. 
 8      */  
 9     FIELD,  
10     /** 
11      * Method declaration. 
12      */  
13     METHOD,  
14     /** 
15      * Parameter declaration. 
16      */  
17     PARAMETER,  
18     /** 
19      * Constructor declaration. 
20      */  
21     CONSTRUCTOR,  
22     /** 
23      * Local variable declaration. 
24      */  
25     LOCAL_VARIABLE,  
26     /** 
27      * Annotation type declaration. 
28      */  
29     ANNOTATION_TYPE,  
30     /** 
31      * Package declaration. 
32      */  
33     PACKAGE  
34 } 

TypeElement  :类

JavaPoet源码初探

TypeSpec是类型元素的抽象,通过Kind枚举定义class、interface、enum、annotation四种类型。

MethodSpec代表方法的抽象。

1     // 元素操作的辅助类
2     Elements elementUtils;
3     //文件相关的辅助类
4     private Filer mFiler;
5     //日志相关的辅助类
6     private Messager mMessager;

1、先添加两个java library,一个annotation,一个compiler:

apt 根据注解,编译时生成代码

annotation library:用于放置注解。

build.gradle文件:注意属于java library,不使用android library。

1  apply plugin: 'java'
2 
3  sourceCompatibility = 1.7
4  targetCompatibility = 1.7
5  dependencies {
6      compile fileTree(dir: 'libs', include: ['*.jar'])
7  }

compile library:用于放置根据注解生成代码类。

build.gradle文件:注意属于java library,不使用android library。

 1 apply plugin: 'java'
 2 
 3 sourceCompatibility = 1.7
 4 targetCompatibility = 1.7
 5 dependencies {
 6     compile fileTree(dir: 'libs', include: ['*.jar'])
 7 
 8     compile 'com.google.auto.service:auto-service:1.0-rc2'
 9     compile 'com.squareup:javapoet:1.7.0'
10     <!-- 引用annotation library  -->
11     compile project(':annotation')
12 }

app module:android app

build.gradle文件:

 1 apply plugin: 'com.android.application'
 2 apply plugin: 'com.neenbedankt.android-apt'
 3 
 4 android {
 5     compileSdkVersion 23
 6     buildToolsVersion "23.0.2"
 7 
 8     defaultConfig {
 9         applicationId "com.example.aptdemo"
10         minSdkVersion 15
11         targetSdkVersion 23
12         versionCode 1
13         versionName "1.0"
14     }
15     buildTypes {
16         release {
17             minifyEnabled false
18             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
19         }
20     }
21 }
22 
23 dependencies {
24     compile fileTree(dir: 'libs', include: ['*.jar'])
25     testCompile 'junit:junit:4.12'
26     compile 'com.android.support:appcompat-v7:24.0.0'
27 
28     compile project(':annotation')
29     apt project(':compiler')
30 }

官方有一个列子的:生成一个java类,然后java 类里面有个main函数

// 注解类 (目录:annotation library)

package com.example;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface Test {
}

// apt生成类 (目录:compiler library)

 1 package com.example;
 2 
 3 import com.google.auto.service.AutoService;
 4 import com.squareup.javapoet.JavaFile;
 5 import com.squareup.javapoet.MethodSpec;
 6 import com.squareup.javapoet.TypeSpec;
 7 import java.io.IOException;
 8 import java.util.Collections;
 9 import java.util.Set;
10 import javax.annotation.processing.AbstractProcessor;
11 import javax.annotation.processing.Processor;
12 import javax.annotation.processing.RoundEnvironment;
13 import javax.lang.model.SourceVersion;
14 import javax.lang.model.element.Modifier;
15 import javax.lang.model.element.TypeElement;
16 
17 @AutoService(Processor.class)
18 public class TestProcessor extends AbstractProcessor {
19 
20     /***
21      package com.example.helloworld;
22 
23      public final class HelloWorld {
24         public static void main(String[] args) {
25             System.out.println("Hello, JavaPoet!");
26         }
27      }
28      */
29 
30     @Override
31     public Set<String> getSupportedAnnotationTypes() {
32         return Collections.singleton(Test.class.getCanonicalName());
33     }
34 
35     @Override
36     public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
37         
38         MethodSpec main = MethodSpec.methodBuilder("main")
39                 .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
40                 .returns(void.class)
41                 .addParameter(String[].class, "args")
42                 .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
43                 .build();
44 
45         TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
46                 .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
47                 .addMethod(main)
48                 .build();
49 
50         JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
51                 .build();
52 
53         try {
54             javaFile.writeTo(processingEnv.getFiler());
55         } catch (IOException e) {
56             e.printStackTrace();
57         }
58 
59         return false;
60     }
61 
62     @Override
63     public SourceVersion getSupportedSourceVersion() {
64         return SourceVersion.RELEASE_7;
65     }
66 }
官方例子

相关文章: