在Android Studio中配置Kotlin Symbol Processing (KSP)

简介

Kotlin Symbol Processing (KSP) 是Google提供的基于Kotlin编译器提供的符号处理工具,相比KAPT有更快的速度。

简单使用方法

此处以Jetpack AndroidX Room的KSP为例,在app的build.gradle.kts中添加以下代码

plugins {
    // ...
    // 导入gradle插件
    id("com.google.devtools.ksp") version "-"
    // ...
}

// ...
// 设定Room的KSP参数
ksp {
    arg("room.schemaLocation", "$projectDir/schemas")
    arg("room.incremental", "true")
}
// ...
// 更换kapt为ksp(因为Room的Kapt和KSP是写在一起的,所以直接更换就好了)
dependencies {
    // ...
    ksp("androidx.room:room-compiler:")
    // ...
}

使用自定义的KSP

只需要创建一个Kotlin module然后按照KSP文档中说明的方法,继承SymbolProcessorSymbolProcessorProvider并实现方法即可。
具体的实现方法请参阅KSP官方文档。如果对Kapt了解的话,还是很容易上手的。另外,目前使用需要添加编译器参数,KotlinPoet也需要KSP版本。

简略的build.gradle.kts如下所示:

plugins {
    kotlin("jvm")
}

tasks.withType().configureEach {
    kotlinOptions {
        jvmTarget = ProjectConfig.javaVersion.toString()
        freeCompilerArgs = freeCompilerArgs + listOf(
            "-opt-in=com.google.devtools.ksp.KspExperimental"
        )
    }
}

dependencies {
    implementation("com.squareup:kotlinpoet-ksp:")
    implementation("com.google.devtools.ksp:symbol-processing-api:")
}

最后别忘了在resources/META-INF/services文件夹下添加com.google.devtools.ksp.processing.SymbolProcessorProvider文件。
其中按行书写KSP的调用类即可。

目前存在的问题

  • 目前由于Android Gradle Plugin (AGP)没有正确识别1.8.21-1.0.11版本的KSP生成的代码,会出现可以编译但是编辑相关代码时红线error的问题。
  • 在使用中也可能会有第一次编译并生成代码成功,修改部分代码后再次编译就无法正确生成代码的问题。

解决方案

  • 在app的build.gradle.kts中添加以下代码指定不同variant使用不同的ksp路径
import com.android.build.api.variant.impl.VariantImpl

android {
    // ...
    androidComponents {
        onVariants { it ->
            if (it is VariantImpl) {
                it.variantData.addJavaSourceFoldersToModel(file("$buildDir/generated/ksp/${it.buildType}/kotlin"))
            }
        }
    }
    // ...
}

另一种解决方案:

import com.android.build.gradle.AppExtension

extensions.getByType().apply {
    applicationVariants.all {
        addJavaSourceFoldersToModel(file("$buildDir/generated/ksp/$name/kotlin"))
    }
}

注:此处使用的Gradle Kotlin DSL编写,若要用groovy请自行修改

  • 在gradle.properties中添加
# 停用KSP的增量编译
ksp.incremental=false

原理:目前AS(2022.2.1 patch 2)每次编译会删除所有旧的生成的代码并添加新的,KSP为了减少工作量会使用增量编译的方式只更新有关联更改的文件。Room的KSP会自动重复添加但是自定义的KSP却不会(目前没找到具体原因,如果有思路欢迎评论)。
注:出现代码无法生成的情况应该是和AGP(8.0.2)兼容性存在问题,关闭增量编译可以解决问题但是可能会减慢速度,所以还需要等Google修复。如果不存在问题不建议添加这个属性。

One more thing

只有在项目中所有的kapt都替换为ksp时才会有较好的编译体验。


Made By XFY9326

你可能感兴趣的:(在Android Studio中配置Kotlin Symbol Processing (KSP))