迁移到内置 Kotlin

Android Gradle 插件 9.0 引入了内置 Kotlin 支持,并默认启用该支持。这意味着,您无需再在 build 文件中应用 org.jetbrains.kotlin.android(或 kotlin-android)插件来编译 Kotlin 源文件。借助内置 Kotlin,您的 build 文件会更简单,并且您可以避免 AGP 与 kotlin-android 插件之间的兼容性问题。

启用内置 Kotlin

您需要使用 AGP 9.0 或更高版本才能获得内置的 Kotlin 支持。 AGP 9.0 已经为应用 AGP 的所有模块启用了内置 Kotlin,因此您无需执行任何操作即可启用它。不过,如果您之前通过在 gradle.properties 文件中设置 android.builtInKotlin=false 选择停用内置 Kotlin,则需要移除该设置或将其设置为 true

内置 Kotlin 需要对项目进行一些更改,因此在启用内置 Kotlin 后,请按照后续步骤迁移项目。

迁移步骤

将项目从旧版 AGP 升级到 AGP 9.0 后,或者在手动启用内置 Kotlin 后,您可能会看到以下错误消息:

Failed to apply plugin 'org.jetbrains.kotlin.android'.
> Cannot add extension with name 'kotlin', as there is an extension already registered with that name.

...或

Failed to apply plugin 'com.jetbrains.kotlin.android'
> The 'org.jetbrains.kotlin.android' plugin is no longer required for Kotlin support since AGP 9.0.

出现此错误的原因是内置 Kotlin 需要对您的项目进行一些更改。 如需解决此错误,请按以下步骤操作:

  1. 移除 kotlin-android 插件
  2. 根据需要迁移 kotlin-kapt 插件
  3. 根据需要迁移 android.kotlinOptions{} DSL
  4. 根据需要迁移 kotlin.sourceSets{} DSL

1. 移除 kotlin-android 插件

从应用 org.jetbrains.kotlin.android(或 kotlin-android)插件的模块级 build 文件中移除该插件。要移除的具体代码取决于您是否使用版本目录来声明插件。

使用版本目录

Kotlin

// Module-level build file
plugins {
    alias(libs.plugins.kotlin.android)
}

Groovy

// Module-level build file
plugins {
    alias(libs.plugins.kotlin.android)
}

无版本目录

Kotlin

// Module-level build file
plugins {
    id("org.jetbrains.kotlin.android")
}

Groovy

// Module-level build file
plugins {
    id 'org.jetbrains.kotlin.android'
}

然后,从顶级 build 文件中移除该插件:

使用版本目录

Kotlin

// Top-level build file
plugins {
    alias(libs.plugins.kotlin.android) apply false
}

Groovy

// Top-level build file
plugins {
    alias(libs.plugins.kotlin.android) apply false
}

无版本目录

Kotlin

// Top-level build file
plugins {
    id("org.jetbrains.kotlin.android") version "KOTLIN_VERSION" apply false
}

Groovy

// Top-level build file
plugins {
    id 'org.jetbrains.kotlin.android' version 'KOTLIN_VERSION' apply false
}

如果您使用版本目录,还需从版本目录 TOML 文件(通常为 gradle/libs.versions.toml)中移除插件定义:

[plugins]
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "KOTLIN_VERSION" }

2. 迁移 kotlin-kapt 插件(如有必要)

org.jetbrains.kotlin.kapt(或 kotlin-kapt)插件与内置 Kotlin 不兼容。如果您使用 kapt,建议您将项目迁移到 KSP

如果您暂时无法迁移到 KSP,请将 kotlin-kapt 插件替换为 com.android.legacy-kapt 插件,并使用与 Android Gradle 插件相同的版本。

例如,使用版本目录时,请按如下方式更新版本目录 TOML 文件:

[plugins]
android-application = { id = "com.android.application", version.ref = "AGP_VERSION" }

# Add the following plugin definition
legacy-kapt = { id = "com.android.legacy-kapt", version.ref = "AGP_VERSION" }

# Remove the following plugin definition
kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "KOTLIN_VERSION" }

然后,更新 build 文件:

Kotlin

// Top-level build file
plugins {
    alias(libs.plugins.legacy.kapt) apply false
    alias(libs.plugins.kotlin.kapt) apply false
}

Groovy

// Top-level build file
plugins {
    alias(libs.plugins.legacy.kapt) apply false
    alias(libs.plugins.kotlin.kapt) apply false
}

Kotlin

// Module-level build file
plugins {
    alias(libs.plugins.legacy.kapt)
    alias(libs.plugins.kotlin.kapt)
}

Groovy

// Module-level build file
plugins {
    alias(libs.plugins.legacy.kapt)
    alias(libs.plugins.kotlin.kapt)
}

3. 根据需要迁移 android.kotlinOptions{} DSL

如果您使用的是 android.kotlinOptions{} DSL,则需要将其迁移到 kotlin.compilerOptions{} DSL。

例如,更新以下代码:

Kotlin

android {
    kotlinOptions {
        languageVersion = "2.0"
        jvmTarget = "11"
    }
}

Groovy

android {
    kotlinOptions {
        languageVersion = "2.0"
        jvmTarget = "11"
    }
}

...到新的 DSL:

Kotlin

kotlin {
    compilerOptions {
        languageVersion = org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0
        // Optional: Set jvmTarget
        // jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
    }
}

Groovy

kotlin {
    compilerOptions {
        languageVersion = org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0
        // Optional: Set jvmTarget
        // jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
    }
}

4. 根据需要迁移 kotlin.sourceSets{} DSL

使用 kotlin-android 插件时,AGP 可让您使用 android.sourceSets{} DSL 或 kotlin.sourceSets{} DSL 添加其他 Kotlin 源目录。借助 android.sourceSets{} DSL,您可以将目录添加到 AndroidSourceSet.kotlin 集或 AndroidSourceSet.java 集。

对于内置 Kotlin,唯一支持的选项是使用 android.sourceSets{} DSL 将目录添加到 AndroidSourceSet.kotlin 集。如果您使用了不受支持的选项,请按如下方式迁移:

Kotlin

# Adding Kotlin source directories to kotlin.sourceSets is not supported
kotlin.sourceSets.named("main") {
    kotlin.srcDir("additionalSourceDirectory/kotlin")
}

# Adding Kotlin source directories to AndroidSourceSet.java is also not supported
android.sourceSets.named("main") {
    java.directories += "additionalSourceDirectory/kotlin"
}

# Add Kotlin source directories to AndroidSourceSet.kotlin
android.sourceSets.named("main") {
    kotlin.directories += "additionalSourceDirectory/kotlin"
}

Groovy

# Adding Kotlin source directories to kotlin.sourceSets is not supported
kotlin.sourceSets.named("main") {
    kotlin.srcDir("additionalSourceDirectory/kotlin")
}

# Adding Kotlin source directories to AndroidSourceSet.java is also not supported
android.sourceSets.named("main") {
    java.directories.add("additionalSourceDirectory/kotlin")
}

# Add Kotlin source directories to AndroidSourceSet.kotlin
android.sourceSets.named("main") {
    kotlin.directories.add("additionalSourceDirectory/kotlin")
}

如果您想向特定变体添加 Kotlin 源目录,或者该目录是由任务生成的,则可以使用变体 API 中的 addStaticSourceDirectoryaddGeneratedSourceDirectory 方法:

Kotlin

androidComponents.onVariants { variant ->
    variant.sources.kotlin!!.addStaticSourceDirectory("additionalSourceDirectory/kotlin")
    variant.sources.kotlin!!.addGeneratedSourceDirectory(TASK_PROVIDER, TASK_OUTPUT)
}

Groovy

androidComponents.onVariants { variant ->
    variant.sources.kotlin!!.addStaticSourceDirectory("additionalSourceDirectory/kotlin")
    variant.sources.kotlin!!.addGeneratedSourceDirectory(TASK_PROVIDER, TASK_OUTPUT)
}

报告问题

如果您在完成上述步骤后遇到问题,请查看问题 #438678642 中的已知问题,并在需要时向我们提供反馈。

选择停用内置 Kotlin

如果您无法迁移项目以使用内置 Kotlin,请在 gradle.properties 文件中设置 android.builtInKotlin=false 以暂时停用它。这样做时,build 会显示一条警告,提醒您迁移到内置 Kotlin,因为在 AGP 10.0 之前的未来版本 AGP 9.x 中,您将无法停用内置 Kotlin。

准备好迁移项目后,请启用内置 Kotlin 并按照迁移步骤操作。

逐个模块迁移

借助 android.builtInKotlin Gradle 属性,您可以为应用 AGP 的所有模块启用或停用内置 Kotlin。

如果您难以一次性迁移所有模块,可以逐个迁移模块:

  1. gradle.properties 文件中设置 android.builtInKotlin=false 以针对所有模块停用内置 Kotlin。

  2. com.android.built-in-kotlin 插件应用到要启用内置 Kotlin 的模块,并使用与 Android Gradle 插件相同的版本。

  3. 按照之前的迁移步骤将此模块迁移到内置 Kotlin。

  4. 迁移完所有模块后,请移除 gradle.properties 中的 android.builtInKotlin=false 设置以及 build 文件中的 com.android.built-in-kotlin 插件。

可以选择性地停用内置 Kotlin

Android Gradle 插件 9.0 会为应用该插件的所有模块启用内置 Kotlin。 我们建议,对于大型项目中没有 Kotlin 源的模块,有选择地停用内置 Kotlin。 这样一来,既移除了 Kotlin 编译任务(该任务会产生少量构建性能开销),也移除了对 Kotlin 标准库的自动依赖项。

如需为模块停用内置 Kotlin,请在该模块的 build 文件中设置 enableKotlin = false

Kotlin

android {
    enableKotlin = false
}

Groovy

android {
    enableKotlin = false
}