APT插件必须使用@Retention(RetentionPolicy.SOURCE)注解,因其仅在源码阶段可见,确保编译期生成Java文件、不污染class文件且语义明确;需继承AbstractProcessor、注册处理器、用Elements/Filer/JavaPoet生成代码,并在Android项目中配置annotationProcessor依赖、启用IDE注解处理及标记生成路径为Sources Root。

APT插件处理 @Retention(RetentionPolicy.SOURCE) 注解,本质是让注解只存在于源码阶段、不进入 class 文件,专为编译期代码生成而设计。它不靠运行时反射,也不改写原有类,而是通过扫描这些“短暂存在”的注解,在 javac 编译过程中实时生成新的 .java 文件——这些文件和手写代码完全等价,会被一并编译进最终的字节码。
为什么必须用 SOURCE 级注解
使用 @Retention(RetentionPolicy.SOURCE) 是 APT 正常工作的前提,原因很直接:
- 编译器只在源码解析阶段暴露 SOURCE 注解给处理器;CLASS 或 RUNTIME 注解在 APT 阶段可能尚未完成写入或不可见
- 避免注解残留:SOURCE 注解不会出现在 class 文件里,不增加 APK 体积,也不影响运行时类加载和反射逻辑
- 语义清晰:明确告诉团队和工具链——这个注解纯属“编译指令”,不是业务配置或运行时元数据
注解处理器如何触发并读取注解
处理器不是自动运行的,它需要被编译器识别并调用。关键步骤包括:
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
- 继承
AbstractProcessor,重写process()方法作为主入口 - 用
@SupportedAnnotationTypes声明要监听的注解全限定名(如"com.example.BindView") - 在
META-INF/services/javax.annotation.processing.Processor中注册类名,或更推荐用@AutoService(Processor.class)自动注册 - 在
process()中调用roundEnv.getElementsAnnotatedWith(BindView.class)获取所有被标注的元素(字段、方法、类等)
从注解信息到 Java 源码的生成逻辑
拿到被注解的元素后,处理器需提取结构化信息,并生成合法、可编译的 Java 代码。典型操作有:
- 用
Elements工具类获取包名、类名、字段类型、注解属性值(如@BindView(R.id.tv)中的R.id.tv) - 用
Filer创建新源文件,路径需严格匹配包结构(如com.example.MainActivity_ViewBinding.java) - 推荐使用
JavaPoet构建代码:它能安全生成带缩进、分号、import 的 Java 源码,避免字符串拼接出错 - 生成的类通常以 “原类名 + 后缀” 命名,并提供静态 bind() 方法,接收 Activity/Fragment 实例,内部调用
findViewById并赋值
Android 项目中必须配置的三处关键点
即使代码写对,缺一配置就会导致 process() 不执行、生成文件不出现、IDE 报红:
-
Gradle 依赖声明:compiler 模块要用
annotationProcessor(非implementation)引入处理器;annotation 模块用api或compileOnly提供给 app 使用 - IDE 启用支持:Android Studio 需开启 Settings → Build → Compiler → Annotation Processors → 勾选 “Enable annotation processing”
-
生成路径识别:确保 IDE 将
build/generated/source/apt/(Gradle)或out/production/generated-sources/annotations/(IntelliJ)标记为 Sources Root,否则无法跳转和补全

















