jkd1.8中文API (可以在API中查看相关类的说明,介绍很详细)
参考《Android进阶之光》第九章注解与依赖注入框架
学习时不明白的地方,尽量要去查清楚,比如在学习编译时注解器时:AbstractProcessor不知道它是做什么的,就可以去查一下jdk1.8中文API有比较详细的解释;这样学下来,可能刚开始学的慢,但是学的比较深入,理解到位
注解概述
注解常用类型:
@Target:注解修饰的对象范围
- ElementType.TYPE: 修饰类,接口或枚举类型
- ElementType.FIELD:修饰成员变量
- ElementType.PARAMETR:修饰参数
- ElementType.METHOD:修饰方法
- 等等 @Retention:声明注解的保留策略
- Retention.RUNTIME: 运行时注解
- Retention.SOURCE: 源码级注解
- Retention.CLASS: 编译时注解
例子学习
1. 运行时注解处理器
定义注解
@Documented
@Retention(RetentionPolicy.RUNTIME) //保留策略为运行时
@Target(ElementType.METHOD) //规定此注解修饰方法
public @interface Swordsman {
String name() default "android";
int age() default 10;
}
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface GET {
String value() default "192.168.0.1";
}
注解处理器
package annotation;
import java.lang.reflect.Method;
public class AnnotationProcessor {
public static void main(String[] args) {
//获取这个类的公共方法
Method[] methods = AnnotationTest.class.getDeclaredMethods();
//遍历这个类的公共方法
for (Method method : methods){
//判断这个方法是否有swordsman注解, Method ,Class, Filed等实现了AnnotatedElement
if (method.isAnnotationPresent(Swordsman.class)){
Swordsman swordsman1 = method.getAnnotation(Swordsman.class);
System.out.println(" swordsman "+swordsman1.name());
}
//判断
if (method.isAnnotationPresent(GET.class)){
GET get = method.getAnnotation(GET.class);
System.out.println("Get 值 "+get.value());
}
}
}
}
2.编译时注解处理器
Android buildGradle 在3.0版本之后采用 annotationProcessor加载注解库
定义注解
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface BindView {
int value() default 1;
}
注解解释器
//继承:AbstractProcessor
//@AutoService(Processor.class)
public class ClassProcessor extends AbstractProcessor {
/**
* @param processingEnvironment 由工具框架返回的处理环境
*/
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
System.out.println("注解处理工具调用");
super.init(processingEnvironment);
}
/**
*
* @param roundEnvironment 用于查询一轮注释处理的信息
*/
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
//TODO Messager 提供注释处理器报告错误消息,警告和其他通知的方式
Messager messager = processingEnv.getMessager();
//返回使用给定注释类型的元素
for (Element element : roundEnvironment.getElementsAnnotatedWith(BindView.class)){
//获取元素的类型 TODO: Element 表示程序元素,如程序包,类、方法、属性等
if (element.getKind() == ElementKind.FIELD){
//打印指定类型的属性名 在这里是打印属性名
messager.printMessage(Diagnostic.Kind.NOTE,"printMessage: "+element.toString());
//打印注解值
messager.printMessage(Diagnostic.Kind.NOTE,"printMessage: "+element.getAnnotation(BindView.class).value());
}
}
return true;
}
/**
* 返回此处理器支持的注释类型的名称
*/
@Override
public Set<String> getSupportedAnnotationTypes() {
//指定这个注解器是注册给哪个注解的
Set<String> annotations = new LinkedHashSet<>();
annotations.add(BindView.class.getCanonicalName());
System.out.println("获取集合 : "+annotations);
return annotations;
}
@Override
public SourceVersion getSupportedSourceVersion() {
//用来指定使用的Java版本
return SourceVersion.latestSupported();
}
}