Android注解
注解(Annotation)
一种元数据(meta data)或是看作一种注释机制。如常用的 @override, @Deprecated等
元注解
修饰注解的注解
@Retention:
表示注解的生命周期。只能有一个。
RetentionPolicy.SOURCE,RetentionPolicy.CLASS, RetentionPolicy.RUNTIME
@Target
表示该注解的目标。可以有多个。
ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE
ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE
@Document
表示该注解包含在class文件中
@Inherited
表示子类将继承父类的注解
自定义注解
public @interface TestAnnotation {
int id() default 0; //只能是public或者默认的访问修饰符
}
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译器完成。
注:不能继承其他的注解或接口
注解参数支持的所有基本类型
- 所有的基本数据类型
- String
- Class
- enum
- Annotation
- 以上所有类型的数组
注解处理
运行时处理
运行时利用发射进行处理,所以需要将注解设置成Runtime级别的,即:
@Retention(RetentionPolicy.RUNTIME)。
缺点:耗时
编译时处理
简介
apt(注解处理器):是javac自带的一个工具,会运行在独立的虚拟机中。
public abstract class TaskManager {
//javac compile task
public TaskProvider<? extends JavaCompile> createJavacTask(...) {
taskFactory.register(new JavaPreCompileTask.CreationAction(scope));
//编译时创建AnnotationTast
boolean processAnnotationsTaskCreated = ProcessAnnotationsTask.taskShouldBeCreated(scope);
if (processAnnotationsTaskCreated) {
taskFactory.register(new ProcessAnnotationsTask.CreationAction(scope));
}
final TaskProvider<? extends JavaCompile> javacTask =
taskFactory.register(
new AndroidJavaCompile.CreationAction(
scope, processAnnotationsTaskCreated));
postJavacCreation(scope);
return javacTask;
}
}
实现
通过继承AbstractProcessor实现
@AutoService(Processor.class)
public class RandomProcessor extends AbstractProcessor{
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) { super.init(processingEnvironment);
}
@Override
public SourceVersion getSupportedSourceVersion() {
return super.getSupportedSourceVersion();
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return super.getSupportedAnnotationTypes();
}
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
return false;
}
}
处理过程中,每一个java文件都可以看做一个静态的、语言级别的结构 -- Element。java文件一共有四种结构:包结构、类和接口、方法、成员变量、方法参数。
package com.example; // PackageElement
public class Example { // TypeElement
private Foo A; // VariableElement
public Foo() {} // ExecutableElement
public setFoo(
Foo other // TypeParameterElement
) {}
}
注解处理
在process方法中,roundEnvironment参数可以帮助我们获取到被注解的Element。接下来就可以对注解元素进行对应的处理。
比如:可以生成java文件(JavaWriter)
打印日志
init方法中,可以得到一个Messager类,用于打印日志,并可以控制日志等级。
@Overrie
public synchronized void init(ProcessingEnvironment environment) {
super.init(environment)
mMessager = environment.getMessager();
mMessager.printMessage(Diagnostic.Kind.NOTE, "Processor init!");
}
注册处理器
要想生效,需要创建META-INF/service/javax.annotation.processing.Processor文件,加入要需要运行的处理器的类。一般可通过@AutoService简单实现
其他
依赖: annotationProcessor vs provided
Debug
建立RemoteDebugger
设置gradle daemon端口和JVM参数。把下面三行加入到你的gradle.properties文件。
org.gradle.daemon=true org.gradle.parallel=true org.gradle.debug=true
然后在Remote Debugger下进行debug。再切换至app下,正常运行app即可开始断点调试。
注意:调试后必须要clean才能进行下一次调试。