Android APT编译时技术 ( 开发编译时注解 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android APT编译时技术 ( 开发编译时注解 )相关的知识,希望对你有一定的参考价值。
一、编译时注解
上一篇博客 【Android APT】编译时技术 ( 编译时注解 和 注解处理器 依赖库 ) 中创建并配置了 annotation 编译时注解 依赖库 和 annotation-compiler 注解处理器 依赖库 ;
本博客开始进行开发 编译时注解 依赖库 ;
开发 annotation 编译时注解 依赖库 ;
右键点击包名 , 选择 " New / Java Class " 选项 ,
在弹出的对话框中 , 选择 " Annotation " 注解对话框 , 然后输入注解名称 BindView ,
注解源码开发 :
package kim.hsl.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.CLASS)
public @interface BindView {
int value();
}
元注解解析 :
使用 @Target(ElementType.FIELD) 元注解标注该 BindView 注解 , 说明该 @BindView 注解是作用于成员变量的 ;
使用 @Retention(RetentionPolicy.CLASS) 标注 BindView 注解 , 说明该注解是 编译时注解 ;
注解属性解析 :
使用 value 作为注解属性名 , 并且只有一个 注解属性 , 因此该注解在使用的时候 , 为注解属性赋值可以省略 " value = " , 直接传入注解属性值 ;
二、编译时注解 使用
注释掉之前的 ButterKnife 的 编译时注解 和 注解处理器 , 使用应用中自己开发的 编译时注解 和 注解处理器 ;
build.gradle 构建脚本 依赖库相关配置 如下 :
dependencies {
//implementation 'com.jakewharton:butterknife:10.2.3'
//annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
annotationProcessor project(path: ':annotation-compiler')
implementation project(path: ':annotation')
}
在 MainActivity 中模仿 ButterKnife 使用 @BindView 注解 , 这是我们自定义的注解 ;
package kim.hsl.apt;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import kim.hsl.annotation.BindView;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.hello)
TextView hello;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//hello.setText("ButterKnife");
}
}
下一步开始使用 注解处理器 , 处理上述注解 ;
注解处理器 工作机制 : 当程序在编译时 , 执行注解处理器 , 注解处理器会搜索整个程序中 , 使用到 BindView 注解的位置 , 并获取注解的相关信息 , 所在字节码文件 , 作用位置 ( 类 / 方法 / 字段等 ) ;
三、注解的保留时间
注解分类 :
① 源码期注解 : 注解保留到源码阶段 , 只有当类是 .java 文件时才能看到 , 一旦编译成 .class 字节码文件 , 该注解就消失了 , 如 @Override 仅在编译时查看父类是否有该方法 ;
② 编译时注解 : 注解保留到字节码阶段 ;
③ 运行时注解 : 注解保留到运行时 ;
源码期注解 与 编译时注解 对比示例 :
查看 MainActivity.java 源码 : 该源码中有两个注解 @BindView 和 @Override 两个注解 ;
查看 BindView 注解的源码如下 , 其中 BindView 注解是被 @Retention(RUNTIME) 修饰的 , 说明该注解是 运行时注解 , 该注解需要从源码 到 字节码 一直保留 , 知道运行时才开始解析该注解 ;
@Retention(RUNTIME) @Target(FIELD)
public @interface BindView {
/** View ID to which the field will be bound. */
@IdRes int value();
}
查看 Override 注解的源码如下 , 该注解被 @Retention(RetentionPolicy.SOURCE) 修饰 , 说明该注解是 源码期注解 , 注解信息仅在源码阶段保存 , 一旦编译成字节码文件 , 高注解就被删除了 ;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
编译应用后 , 查看 MainActivity.class 字节码文件 , 该字节码文件在 " APT\\app\\build\\intermediates\\javac\\debug\\classes\\kim\\hsl\\apt " 目录下 ;
字节码文件中的 @Override 注解已经消失 , @BindView 注解还存在 ;
@Override 注解是 源码期注解 , 只保留到源码期 , 编译时使用该注解 , 编译完成后 , 该注解就被删除了 ;
@BindView 注解 是 运行时注解 , 该注解需要在运行时使用 , 需要一直保留到运行时 ;
四、博客资源
博客源码 :
以上是关于Android APT编译时技术 ( 开发编译时注解 )的主要内容,如果未能解决你的问题,请参考以下文章
Android APT编译时技术 ( 编译时注解 和 注解处理器 依赖库 )
字节码插桩Android 打包流程 | Android 中的字节码操作方式 | AOP 面向切面编程 | APT 编译时技术