编译时注解处理器
目录结构
(1) 定义注解
首先在项目中新建一个 Java Libray 来专门存放注解,这个 Library 名为 annotations。接着在 annotations 下新建 BindView 注解。
@Retention(CLASS)
@Target(ElementType.FIELD)
public @interface BindView {
int value() default 1;
}
(2)编写注解处理器
首先在项目中新建一个 Java Libray 来专门存放注解处理器,这个 Library 名为 processor。接着在 annotations 下新建注解处理器 ClassProcessor 并继承于 AbstractProcessor。但在编写 ClassProcessor 之前我们要先配置 processor 库的 build.gradle:
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':annotations')
}
sourceCompatibility = "7"
targetCompatibility = "7"
接着我们写一下 ClassProcessor 这个注解处理器类:
public class ClassProcessor extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
}
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
Messager messager = processingEnv.getMessager();
for (Element element :roundEnvironment.getElementsAnnotatedWith(BindView.class)){
if (element.getKind() == ElementKind.FIELD){
//打印出注解修饰的成员变量的名称,这个名称会在 Gradle Console 窗口中打印出来。
messager.printMessage(Diagnostic.Kind.NOTE,"printMessage:"+element.toString());
}
}
return true;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> annotations = new LinkedHashSet<String>();
annotations.add(BindView.class.getCanonicalName());
return annotations;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
}
- init: 被注解处理工具调用,并输入 ProcessingEnvironment 参数。ProcessingEnvironment 提供很多有用的工具类,比如 Elements 、Types、Filer 和 Messager 等。
- process: 相当于每个处理器的主函数 main() ,在这里写你的扫描、评估和处理注解的代码,以及生成 Java 文件。输入参数 RoundEnviroment,可以让你查询出包含特定注解的被注解元素。
- getSupportedAnnotationTypes:这是必须指定的方法,指定这个注解处理器时注册给哪个注解的。注意,它的返回值是一个字符串的集合,包含本处理器想要处理的注解类型的合法全称。
- getSupportedSourceVersion:用来指定你使用的 Java 版本,通常这里返回 SourceVersion.latestSupported()。
(3)注册注解处理器
为了能使用注解处理器,需要用一个服务文件来注册它。现在来创建这个服务文件。首先在 processor 库的 main 目录下新建 resources 资源文件夹,接下来在 resources 中再建立 META-INF/services 目录文件夹。最后在这个文件夹里创建 javax.annotation.processing.Processor 文件,这个文件中的内容是注解处理器的名称。即 com.example.processor.ClassProcessor。
(4)应用注解
在主工程项目 (app) 中引用注解。首先在 app 里的 build.graldle 中引用 annotations 和 processor 这两个库:
dependencies {
...
implementation project(':annotations')
annotationProcessor project(':processor')
}
最后在 MainActivity 中应用注解便可。
public class MainActivity extends AppCompatActivity {
@BindView(value = R.id.tv_name)
private TextView tv_name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
最后先 Clean Project 再 Make Project ,在 Gradle Console 窗口中便会打印出:
注:printMessage:tv_name