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 :类
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:
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 }