为 KMP 设置 Android Gradle 库插件

com.android.kotlin.multiplatform.library Gradle 插件是官方支持的工具,用于向 Kotlin Multiplatform (KMP) 库模块添加 Android 目标。它可以简化项目配置、提升 build 性能,并提供与 Android Studio 的更好集成。

com.android.library 插件用于 KMP 开发取决于 Android Gradle 插件 API,这些 API 已被废弃,并且需要在 Android Gradle 插件 9.0 及更高版本(2025 年第 4 季度)中选择启用。预计这些 API 将在 Android Gradle 插件 10.0 (2026 年下半年)中移除。

如需应用此插件,请参阅应用 Android-KMP 插件 部分。如果您需要从旧版 API 迁移,请查看迁移 指南

如需获得有关 AGP 9.0 及更高版本迁移的帮助,您可以使用 JetBrains 为 KMP 应用创建的 代理技能 。如需详细了解如何在 Android Studio 中使用技能,请参阅使用技能扩展智能体模式。请注意,AI 结果并非完全可预测。

主要特性和区别

Android-KMP 插件专为 KMP 项目量身定制,在几个关键方面与标准 com.android.library 插件不同:

  • 单变体架构 :该插件使用单变体,移除了对产品变种和 build 类型的支持,从而简化了配置并提升了 build 性能。

  • 针对 KMP 进行了优化 :该插件专为 KMP 库设计,专注于共享 Kotlin 代码和互操作性,省略了对 Android 专用原生 build、AIDL 和 RenderScript 的支持。

  • 默认停用测试 :默认情况下,单元测试和设备(插桩)测试均处于停用状态,以提高 build 速度。您可以根据需要启用它们。

  • 没有顶级 Android 扩展 :配置通过 Gradle KMP DSL 中的 android 代码块处理,从而保持一致的 KMP 项目结构。没有顶级 android 扩展代码块。

  • 选择启用 Java 编译 :默认情况下,Java 编译处于停用状态。在 android 代码块中使用 withJava() 即可启用它。这样可以在不需要 Java 编译时缩短 build 时间。

Android-KMP 库插件的优势

Android-KMP 插件为 KMP 项目提供了以下优势:

  • 提升了 build 性能和稳定性 :它专为优化 build 速度和提升 KMP 项目内的稳定性而设计。它专注于 KMP 工作流,有助于实现更高效、更可靠的构建流程。

  • 增强了 IDE 集成 :在使用 KMP Android 库时,它提供了更好的代码补全、导航、调试和整体开发者体验。

  • 简化了项目配置 :该插件移除了 build 变体等 Android 专用复杂性,从而简化了 KMP 项目的配置。这样可以获得更简洁、更易于维护的 build 文件。 以前,在 KMP 项目中使用 com.android.library 插件可能会创建令人困惑的源代码集名称,例如 androidAndroidTest。对于熟悉标准 KMP 项目结构的开发者来说,这种命名惯例不太直观。

针对不支持的功能的解决方法

与使用 com.android.library 插件进行 KMP 集成相比,com.android.kotlin.multiplatform.library 插件缺少一些功能。以下是针对不支持的功能的解决方法:

  • build 变体

    不支持 build 类型和产品变种。这是因为新插件使用单变体架构,从而简化了配置并提升了 build 性能。

    如果您需要 build 变体,我们建议您使用 com.android.library 插件创建一个单独的独立 Android 库模块,在该模块中配置 build 类型和产品变种,然后从 Kotlin Multiplatform 库的 androidMain 源代码集中将其作为标准项目依赖项使用。 如需了解详情,请参阅创建 Android 库配置 build 变体

  • 数据绑定和视图绑定

    这些是 Android 专用的界面框架功能,与 Android 视图系统和 XML 布局紧密相关。在新 Android-KMP 库插件中,我们 建议您使用 Compose Multiplatform等多平台框架处理界面。数据绑定和视图绑定被视为最终 Android 应用的实现细节,而不是可共享的库。

  • 原生 build 支持

    新插件专注于为 Android 目标生成标准 AAR。 Kotlin Multiplatform 中的原生代码集成由 KMP 自己的原生目标(例如 androidNativeArm64androidNativeX86)及其 C 互操作功能直接处理。如果您需要添加原生 C/C++ 代码,应将其定义为通用或原生源代码集的一部分,并在 kotlin 代码块内配置 C 互操作,而不是使用 Android 专用的 externalNativeBuild 机制。

    或者,如果您需要通过 externalNativeBuild 提供原生 build 支持,我们建议您创建一个单独的独立 com.android.library 模块,您可以在其中集成原生代码,并从 Kotlin Multiplatform 库项目的 androidMain 源代码集中使用该独立库。 如需了解详情,请参阅创建 Android 库向您的项目添加 C 和 C++ 代码

  • BuildConfig

    BuildConfig 功能在多变体环境中最为有用。由于新的 Kotlin Multiplatform 库插件与变体无关,并且缺少对 build 类型和产品变种的支持,因此未实现此功能。作为替代方案,我们建议您使用 BuildKonfig 插件或类似的社区解决方案为所有目标生成元数据。

前提条件

如需使用 com.android.kotlin.multiplatform.library 插件,您的项目必须配置以下最低版本或更高版本:

  • Android Gradle 插件 (AGP):8.10.0
  • Kotlin Gradle 插件 (KGP):2.0.0

将 Android-KMP 插件应用于现有模块

如需将 Android-KMP 插件应用于现有 KMP 库模块,请按以下步骤操作:

  1. 在版本目录中声明插件。打开版本目录 TOML 文件(通常为 gradle/libs.versions.toml),然后添加插件定义部分:

    # To check the version number of the latest Kotlin release, go to
    # https://kotlinlang.org/docs/releases.html
    
    [versions]
    androidGradlePlugin = "9.1.0"
    kotlin = "KOTLIN_VERSION"
    
    [plugins]
    kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
    android-kotlin-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "androidGradlePlugin" }
    
  2. 在根 build 文件中应用插件声明。打开位于项目根目录中的 build.gradle.kts 文件。使用 apply false 将插件别名添加到 plugins 代码块。这样,插件别名便可供所有子项目使用,而无需将插件逻辑应用于根项目本身。

    Kotlin

    // Root build.gradle.kts file
    
    plugins {
       alias(libs.plugins.kotlin.multiplatform) apply false
    
       // Add the following
       alias(libs.plugins.android.kotlin.multiplatform.library) apply false
    }

    Groovy

    // Root build.gradle file
    
    plugins {
       alias(libs.plugins.kotlin.multiplatform) apply false
    
       // Add the following
       alias(libs.plugins.android.kotlin.multiplatform.library) apply false
    }
  3. 在 KMP 库模块 build 文件中应用插件。打开 KMP 库模块中的 build.gradle.kts 文件,然后在 plugins 代码块内的文件顶部应用插件:

    Kotlin

    // Module-specific build.gradle.kts file
    
    plugins {
       alias(libs.plugins.kotlin.multiplatform)
    
       // Add the following
       alias(libs.plugins.android.kotlin.multiplatform.library)
    }

    Groovy

    // Module-specific build.gradle file
    
    plugins {
       alias(libs.plugins.kotlin.multiplatform)
    
       // Add the following
       alias(libs.plugins.android.kotlin.multiplatform.library)
    }
  4. 配置 Android KMP 目标。配置 Kotlin Multiplatform 代码块 (kotlin) 以定义 Android 目标。在 kotlin 代码块内,使用 android 指定 Android 目标:

    Kotlin

    kotlin {
       android {
           namespace = "com.example.kmpfirstlib"
           compileSdk = 33
           minSdk = 24
    
           withJava() // enable java compilation support
           withHostTestBuilder {}.configure {}
           withDeviceTestBuilder {
               sourceSetTreeName = "test"
           }
    
           compilerOptions.configure {
               jvmTarget.set(
                   org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8
               )
           }
       }
    
       sourceSets {
           androidMain {
               dependencies {
                   // Add Android-specific dependencies here
               }
           }
           getByName("androidHostTest") {
               dependencies {
               }
           }
    
           getByName("androidDeviceTest") {
               dependencies {
               }
           }
       }
       // ... other targets (JVM, iOS, etc.) ...
    }

    Groovy

    kotlin {
       android {
           namespace = "com.example.kmpfirstlib"
           compileSdk = 33
           minSdk = 24
    
           withJava() // enable java compilation support
           withHostTestBuilder {}.configure {}
           withDeviceTestBuilder {
               it.sourceSetTreeName = "test"
           }
    
           compilerOptions.options.jvmTarget.set(
               org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8
           )
       }
    
       sourceSets {
           androidMain {
               dependencies {
               }
           }
           androidHostTest {
               dependencies {
               }
           }
           androidDeviceTest {
               dependencies {
               }
           }
       }
       // ... other targets (JVM, iOS, etc.) ...
    }
  5. 应用更改。应用插件并配置 kotlin 代码块后,同步 Gradle 项目以应用更改。

从旧版插件迁移

本指南可帮助您从旧版 com.android.library 插件迁移到 com.android.kotlin.multiplatform.library 插件。

1. 移动来源

旧版插件允许您使用 src/mainsrc/testsrc/androidTest 源代码集,以及 src/androidMainsrc/androidHostTestsrc/androidDeviceTest。新插件仅使用后者的源代码目录,因此您需要将来源从 src/main 移动到 src/androidMain,从 src/test 移动到 src/androidHostTest,以及从 src/androidTest 移动到 src/androidDeviceTest

2. 声明依赖项

一项常见任务是为 Android 专用源代码集声明依赖项。与之前使用的通用 dependencies 代码块不同,新插件要求将这些依赖项明确放置在 sourceSets 代码块内。

Android-KMP

新插件通过将 Android 依赖项分组到 androidMain 源代码集中,从而提升了结构的简洁性。除了主源代码集之外, 还有两个测试源代码集(按需创建): androidDeviceTestandroidHostTest(如需了解详情,请参阅配置主机和 设备测试)。

// build.gradle.kts

kotlin {
    android {}
    //... other targets

    sourceSets {
        commonMain.dependencies {
            implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
        }

        // Dependencies are now scoped to the specific Android source set
        androidMain.dependencies {
            implementation("androidx.appcompat:appcompat:1.7.0")
            implementation("com.google.android.material:material:1.11.0")
        }
    }
}

源代码集具有相应的 Kotlin 编译,分别命名为 maindeviceTesthostTest。您可以在 build 脚本中配置源代码集和编译,如下所示:

// build.gradle.kts

kotlin {
    android {
        compilations.getByName("deviceTest") {
            kotlinOptions.languageVersion = "2.0"
        }
    }
}

旧版插件

使用旧版插件时,您可以在顶级依赖项代码块中声明 Android 专用依赖项,这有时可能会在多平台模块中造成混淆。

// build.gradle.kts

kotlin {
  androidTarget()
  //... other targets
}

// Dependencies for all source sets were often mixed in one block
dependencies {
  // Common dependencies
  commonMainImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")

  // Android-specific dependencies
  implementation("androidx.appcompat:appcompat:1.7.0")
  implementation("com.google.android.material:material:1.11.0")
}

3. 启用 Android 资源

为了优化 build 性能,新插件默认未启用对 Android 资源(res 文件夹)的支持。您必须选择启用才能使用它们。这项变更有助于确保不需要 Android 专用资源的项目不会因相关的 build 开销而受到影响。

Android-KMP

您必须明确启用 Android 资源处理。资源应放置在 src/androidMain/res 中。

// build.gradle.kts

kotlin {
  android {
    // ...
    // Enable Android resource processing
    androidResources {
      enable = true
    }
  }
}

// Project Structure
// └── src
//     └── androidMain
//         └── res
//             ├── values
//             │   └── strings.xml
//             └── drawable
//                 └── icon.xml

旧版插件

资源处理默认处于启用状态。您可以立即在 src/main 中添加 res 目录,并开始添加 XML 可绘制对象、值等。

// build.gradle.kts

android {
    namespace = "com.example.library"
    compileSdk = 34
    // No extra configuration was needed to enable resources.
}

// Project Structure
// └── src
//     └── main
//         └── res
//             ├── values
//             │   └── strings.xml
//             └── drawable
//                 └── icon.xml

4. 配置主机和设备测试

新插件的一项重大变更是,Android 主机端(单元)和设备端(插桩)测试默认处于停用状态 。您必须明确选择启用才能创建测试源代码集和配置,而旧版插件会自动创建它们。

这种选择启用模式有助于验证您的项目是否保持精简,并且仅包含您主动使用的 build 逻辑和源代码集。

Android-KMP

在新插件中,您可以在 kotlin.android 代码块内启用和配置测试。这样可以使设置更加明确,并避免创建未使用的测试组件。androidUnitTest 源代码集变为 androidHostTest(测试目录从 src/androidUnitTest 更改为 src/androidHostTest),而 androidInstrumentedTest 变为 androidDeviceTest(测试目录从 src/androidInstrumentedTest 更改为 src/androidDeviceTest)。

// build.gradle.kts

kotlin {
  android {
    // ...

    // Opt-in to enable and configure host-side (unit) tests
    withHostTest {
      isIncludeAndroidResources = true
    }

    // Opt-in to enable and configure device-side (instrumented) tests
    withDeviceTest {
      instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
      execution = "HOST"
    }
  }
}

// Project Structure (After Opt-in)
// └── src
//     ├── androidHostTest
//     └── androidDeviceTest

旧版插件

使用 com.android.library 插件时,系统默认会创建 androidUnitTestandroidInstrumentedTest 源代码集。您可以在 android 代码块内配置其行为,通常使用 testOptions DSL。

// build.gradle.kts

android {
  defaultConfig {
    // Runner was configured in defaultConfig
    testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
  }

  testOptions {
    // Configure unit tests (for the 'test' source set)
    unitTests.isIncludeAndroidResources = true

    // Configure device tests (for the 'androidTest' source set)
    execution = "HOST"
  }
}

// Project Structure (Defaults)
// └── src
//     ├── test
//     └── androidTest

5. 启用 Java 源代码编译

如果您的 KMP 库需要为其 Android 目标编译 Java 源代码,您必须使用新插件明确启用此功能。请注意,这会为直接位于项目中的 Java 文件启用编译,而不是为其依赖项启用编译。设置 Java 和 Kotlin 编译器 JVM 目标版本的方法也会发生变化。

Android-KMP

您必须通过调用 withJava() 来选择启用 Java 编译。现在,JVM 目标直接在 kotlin { android {} } 代码块内配置,以实现更统一的设置。在此处设置 jvmTarget 同时适用于 Android 目标的 Kotlin 和 Java 编译。

// build.gradle.kts

kotlin {
  android {
    //  Opt-in to enable Java source compilation
    withJava()
    // Configure the JVM target for both Kotlin and Java sources
    compilerOptions {
      jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8)
    }
  }
  // ...
}

// Project Structure:
// └── src
//     └── androidMain
//         ├── kotlin
//         │   └── com/example/MyKotlinClass.kt
//         └── java
//             └── com.example/MyJavaClass.java

旧版插件

Java 编译默认处于启用状态。Java 和 Kotlin 来源的 JVM 目标在 android 代码块中使用 compileOptions 设置。

// build.gradle.kts

android {
  // ...
  compileOptions {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
  }
}

kotlin {
  androidTarget {
    compilations.all {
      kotlinOptions.jvmTarget = "1.8"
    }
  }
}

6. 使用 androidComponents 与 build 变体互动

androidComponents 扩展仍可用于以编程方式与 build 工件互动。虽然 Variant API 的大部分内容保持不变, 但新的 AndroidKotlinMultiplatformVariant 接口更加受限,因为 该插件仅生成单个变体。

因此,与 build 类型和产品变种相关的属性不再在变体对象上可用。

Android-KMP

onVariants 代码块现在会遍历单个变体。您仍然可以访问 nameartifacts 等常见属性,但无法访问 build 类型专用属性。

// build.gradle.kts

androidComponents {
  onVariants { variant ->
      val artifacts = variant.artifacts
  }
}

旧版插件

使用多个变体时,您可以访问 build 类型专用属性来配置任务。

// build.gradle.kts

androidComponents {
  onVariants(selector().withBuildType("release")) { variant ->
    // ...
  }
}

7. 选择 Android 库依赖项的变体

您的 KMP 库为 Android 生成单个变体。但是,您可能依赖于具有多个变体(例如 free/paid 产品变种)的标准 Android 库 (com.android.library)。控制项目如何从该依赖项中选择变体是一项常见要求。

Android-KMP

新插件在 kotlin.android.localDependencySelection 代码块内集中并阐明了此逻辑。这样可以更清楚地了解将为您的单变体 KMP 库选择哪些外部依赖项变体。

// build.gradle.kts
kotlin {
  android {
    localDependencySelection {
      // For dependencies with multiple build types, select 'debug' first, and 'release' in case 'debug' is missing
      selectBuildTypeFrom.set(listOf("debug", "release"))

      // For dependencies with a 'type' flavor dimension...
      productFlavorDimension("type") {
        // ...select the 'typeone' flavor.
        selectFrom.set(listOf("typeone"))
      }
    }
  }
}

旧版插件

您可以在 buildTypes and productFlavors 代码块内配置依赖项选择策略。这通常涉及使用 missingDimensionStrategy 为库没有的维度提供默认变种,或在特定变种中使用 matchingFallbacks 来定义搜索顺序。

如需详细了解 API 用法,请参阅解决匹配错误

8. Compose 预览依赖项

通常,我们希望将特定库限定在本地开发环境中,以防止内部工具泄露到最终发布的工件中。对于新的 KMP Android 插件,这会成为一个挑战,因为它移除了用于将开发依赖项与发布代码分开的 build 类型架构。

Android-KMP

如需仅为本地开发和测试添加依赖项,请将依赖项直接添加到主 Android 编译的运行时类路径配置(在顶级 dependencies 代码块中)。这有助于确保 依赖项在运行时可用(例如,对于 Compose 预览等工具),但不是编译 类路径或库的已发布 API 的一部分。

// build.gradle.kts
dependencies {
  "androidRuntimeClasspath"(libs.androidx.compose.ui.tooling)
}

旧版插件

对于使用 com.android.library 插件作为 Android 目标的 Kotlin Multiplatform 项目,应使用 debugImplementation 配置,该配置将依赖项限定在调试 build 类型,并防止其包含在消费者使用的库的发布变体中。

// build.gradle.kts
dependencies {
  debugImplementation(libs.androidx.compose.ui.tooling)
}

9. 为 KMP Android 目标配置 JVM 目标

KMP Android 插件使用 android.compilerOptions.jvmTarget 设置 JVM 目标,该目标同时适用于 Java 和 Kotlin,与纯 Android 项目中单独的 compileOptionskotlinOptions 代码块相比,简化了配置。

Android-KMP

使用包含 Android 目标的 Kotlin Multiplatform (KMP) 项目时,您可以通过多种方式为 Kotlin 和 Java 编译器配置 JVM 目标版本。了解这些配置的范围和层次结构是管理项目字节码兼容性的关键。

以下是设置 JVM 目标的三种主要方式,按优先级从低到高排序。优先级较高的 JVM 目标值适用于配置的目标的较小子集,并覆盖优先级较低的值,这意味着您可以为项目中的不同目标和目标内的编译设置不同的 JVM 版本。

使用 Kotlin 工具链(最低优先级)

设置 JVM 目标的最通用方法是在 build.gradle.kts 文件的 kotlin 代码块中指定工具链。此方法为项目中所有基于 JVM 的目标(包括 Android)设置 Kotlin 和 Java 编译任务的目标。

// build.gradle.kts
kotlin {
    jvmToolchain(21)
}

此配置使 kotlincjavac 都以 JVM 21 为目标。这是为整个项目建立一致基准的好方法。

使用 Android 目标级编译器选项(中等优先级)

您可以在 android 代码块内专门为 Android KMP 目标指定 JVM 目标。此设置会覆盖项目范围内的 jvmToolchain 配置,并适用于所有 Android 编译。

// build.gradle.kts
kotlin {
    android {
        compilerOptions {
            jvmTarget.set(JvmTarget.JVM_11)
        }
    }
}

在这种情况下,即使 jvmToolchain 设置为其他版本,Android 目标的 Kotlin 和 Java 代码也会编译为以 JVM 11 为目标。

使用编译级编译器选项(最高优先级)

如需实现最精细的控制,您可以根据每个编译配置编译器选项(例如,仅针对 androidMainandroidHostTest)。如果特定编译需要以不同的 JVM 版本为目标,这会非常有用。此设置会覆盖 Kotlin 工具链和 Android 目标级选项。

// build.gradle.kts
kotlin {
    android {
        compilations.all {
            compileTaskProvider.configure {
                compilerOptions.jvmTarget.set(JvmTarget.JVM_11)
            }
        }
    }
}

此配置有助于确保 Android 目标中的所有编译都使用 JVM 11,从而提供精细的控制。

旧版插件

在使用标准 Android 库插件 (com.android.library) 的 KMP 项目中,配置与使用 KMP Android 插件时略有不同(但概念上类似)。

使用 Kotlin 工具链

kotlin.jvmToolchain() 方法的工作方式相同,为 Java 设置 sourceCompatibilitytargetCompatibility,为 Kotlin 设置 jvmTarget。我们建议使用此方法。

// build.gradle.kts
kotlin {
    jvmToolchain(21)
}

compileOptions 和 kotlinOptions

如果您不使用 Kotlin 工具链,则必须使用单独的代码块为 Java 和 Kotlin 配置 JVM 目标。

// build.gradle.kts
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }

    kotlinOptions {
        jvmTarget = "11"
    }
}

10. 发布使用方 keep 规则

如果您的 KMP 库需要为其使用方提供使用方 keep 规则(例如 R8 的 ProGuard 规则),您需要在新插件中明确启用发布。以前,如果指定了使用方 keep 规则,则默认会发布这些规则。

Android-KMP

使用新插件时,您必须设置 optimization.consumerKeepRules.publish = true,并在 consumerKeepRules代码块内指定规则文件,才能发布使用方 keep 规则。

// build.gradle.kts
kotlin {
  android {
    optimization {
      consumerKeepRules.apply {
        publish = true
        file("consumer-proguard-rules.pro")
      }
    }
  }
}

旧版插件

使用 com.android.library 时,在 android.defaultConfig 中使用 consumerProguardFiles 指定的任何规则文件都会默认发布到库的工件中。

// build.gradle.kts
android {
  defaultConfig {
    consumerProguardFiles("consumer-proguard-rules.pro")
  }
}

11. 将库发布到 Maven

如果您计划将 KMP 库发布到 Maven 以供其他项目使用,则该流程会有所不同,具体取决于您使用的是新的 Android-KMP 插件还是旧版插件。

Android-KMP

com.android.kotlin.multiplatform.library 插件与标准 Kotlin Multiplatform 发布机制集成。除了标准 KMP 库发布流程之外,无需执行任何 Android 专用步骤。

如需发布库,请参阅 JetBrains 的官方文档: 为多平台库设置发布

旧版插件

在 KMP 项目中将 com.android.library 用于 Android 目标时,您需要按照标准 Android 库发布指南准备和发布 Android 专用工件 (.aar)。

如需了解详细说明,请参阅 准备库以供发布

插件 API 参考文档

新插件具有与 com.android.library 不同的 API Surface。如需详细了解新的 DSL 和接口,请参阅 API 参考文档:

Android-KMP 库插件中的已知问题

以下是在应用新的 com.android.kotlin.multiplatform.library 插件时可能会发生的已知问题: