一、引言
1. 什么是APT?
2. Kotlin注解处理器KAPT存在的问题?
3. Kotlin符号处理器KSP有哪些优势?
4. 如何从KAPT迁移至KSP?
二、APT简介
APT(Annotation Processing Tool)注解处理工具,是 Java 语言提供的一种编译时处理注解的机制,如Retrofit、EventBus、ButterKnife等使用了APT。
三、KAPT是什么
KAPT(Kotlin Annotation Processing Tool),Kotlin注解处理工具 。其作用是处理Kotlin代码中的注解,实现如自动化代码生成、代码正确性检查等功能。
1. KAPT使用场景
Data Binding,它允许开发者使用声明式的方式将UI组件和数据源进行绑定,而无需编写大量的样板代码来手动更新视图,让数据的变化自动反映在 UI 上。
步骤1:
apply plugin: 'kotlin-kapt'
步骤2:
android {
dataBinding.enabled = true
}
步骤3:
dependencies {
kapt "com.android.databinding:compiler:version"
}
Kapt使用机制
Kotlin官方用于解析Metadata的库
api("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.3.0")
2. KAPT存在的问题
编译耗时,需要先将Kotlin类先转化成Java Stubs。
如果工程模块引入了 ‘kotlin-kapt’,相应的模块构建过程中会增加如下两个Task:
kaptGenerateStubs
${variant}
Kotlin、**kapt${variant}
Kotlin **
KAPT并没有直接解析Kotlin源码,而是需要将Kotlin类先转化成Java Stubs,再交由APT处理,这样会增加编译耗时:kaptGenerateStubs${variant}
Kotlin多了近7min。
KaptKotlin执行流程:
step1:定位处理器:kaptTask定位kapt注册的kapt插件,找到所有与之相关的processors,这些processors用于后续对注解的处理操作。
step2:生成抽象语法树:kaptTask调用JDK方法,对源文件进行解析,从而生成对应的AST(抽象语法树)。AST以树状结构表示源代码的语法结构,方便后续注解处理过程中的信息提取。
step3执行注解处理:kaptTask调用JDK进行annotation processing。在JDK内部,会回调步骤1中找到的processors,并执行processors。
step4:迭代处理新生成文件:业务方的processors完成写入新Java文件的逻辑。由于新Java文件可能引用了processor注册的注解,JDK会携带新的Java文件进行第二轮、第三轮,甚至更多轮次的process处理。
四、KSP
1.什么是元编程 Meta Programming
• 元编程:编写以程序作为数据的程序
• 编译器、链接器、解释器、调试工具、程序分析工具等等
• 编译时处理源码、中间代码以生成或修改源码、中间代码的程序
• 运行时读取类、函数的数据以执行某种动态逻辑的程序
• 内省:运行时读取程序自身信息
• 反射:运行时读取程序自身信息并修改其结构和行为
2.什么时候需要元编程?
• 当我们写了很多模板代码的时候
• 当我们写了很多重复代码的时候
• 当我们想要隐藏一些实现细节的时候
很多库都会使用注解简化模板代码,例如 Room、Retrofit等,Kotlin代码使用处理注解,本质上是基于APT工作的,APT只能处理Java注解,因此需要先生成 APT可解析的Java Stubs ,这影响了Kotlin的整体编译速度。
KSP(Kotlin Symbol Processing,KSP)不需要生成额外的Java Stubs。
KSP 的开发流程和KAPT类似:
step1:解析源码AST
step2:生成代码
step3:生成的代码与源码一起参与Kotlin编译
tips:需要注意 KSP 不能用来修改原代码,只能用来生成新代码