为 KMP 设置 Android Gradle 库插件

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

使用 com.android.library 插件进行 KMP 开发依赖于已弃用的 Android Gradle 插件 API,并且在 Android Gradle 插件 9.0 及更高版本(2025 年第 4 季度)中需要选择启用。我们预计会在 Android Gradle 插件 10.0(2026 年下半年)中移除这些 API。

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

主要功能和区别

Android-KMP 插件专门针对 KMP 项目量身打造,在几个关键方面与标准 com.android.library 插件有所不同:

  • 单一变体架构:插件使用单一变体,不再支持产品变种和 build 类型,从而简化配置并提升 build 性能。

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

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

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

  • 选择启用 Java 编译:Java 编译默认处于停用状态。在 androidLibrary 块中使用 withJava() 即可启用该功能。这样可以缩短不需要 Java 编译时的构建时间。

Android-KMP 库插件的优势

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

  • 提升了构建性能和稳定性:它经过精心设计,可优化 KMP 项目中的构建速度并提高稳定性。它专注于 KMP 工作流,有助于提高构建流程的效率和可靠性。

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

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

前提条件

如需使用 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 = "8.13.2"
    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 块中,使用 androidLibrary 指定 Android 目标平台:

    Kotlin

    kotlin {
       androidLibrary {
           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 {
       androidLibrary {
           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. 声明依赖项

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

Android-KMP

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

// build.gradle.kts

kotlin {
    androidLibrary {}
    //... 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 {
    androidLibrary {
        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")
}

2. 启用 Android 资源

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

Android-KMP

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

// build.gradle.kts

kotlin {
  androidLibrary {
    // ...
    // 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

3. 配置主机和设备测试

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

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

Android-KMP

在新插件中,您可以在 kotlin.androidLibrary 代码块内启用和配置测试。这样可以使设置更加明确,并避免创建未使用的测试组件。test 源集变为 androidHostTestandroidTest 变为 androidDeviceTest

// build.gradle.kts

kotlin {
  androidLibrary {
    // ...

    // 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 插件时,系统默认创建了 testandroidTest 来源集。您可以在 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

4. 启用 Java 源代码编译

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

Android-KMP

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

// build.gradle.kts

kotlin {
  androidLibrary {
    //  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"
    }
  }
}

5. 使用 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 ->
    // ...
  }
}

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

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

Android-KMP

新插件将此逻辑集中并明确地放在 kotlin.androidLibrary.localDependencySelection 块中。这样一来,您就可以更清楚地了解将为单变体 KMP 库选择哪些外部依赖项变体。

// build.gradle.kts
kotlin {
  androidLibrary {
    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 用法,请参阅解决匹配错误

7. Compose 预览依赖项

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

Android-KMP

如需仅为本地开发和测试添加依赖项,请将该依赖项直接添加到主 Android 编译的运行时类路径配置(在顶级 dependencies 代码块中)。这有助于确保依赖项在运行时可用(例如,对于 Compose 预览等工具),但不会成为编译 classpath 或库的已发布 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)
}

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

KMP Android 插件使用 androidLibrary.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 {
    androidLibrary {
        compilerOptions {
            jvmTarget.set(JvmTarget.JVM_11)
        }
    }
}

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

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

如需获得最精细的控制,您可以按每次编译配置编译器选项(例如,仅针对 androidMainandroidHostTest)。如果特定编译需要以其他 JVM 版本为目标平台,则此功能非常有用。此设置会替换 Kotlin 工具链和 Android 目标级选项。

// build.gradle.kts
kotlin {
    androidLibrary {
        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"
    }
}

插件 API 参考文档

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

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

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

不支持的功能

与使用 com.android.library 插件的 KMP 集成相比,com.android.kotlin.multiplatform.library 插件缺少以下功能:

  • 数据绑定和视图绑定

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

  • 原生 build 支持

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

    或者,如果您需要原生 build 支持,我们建议您创建一个单独的 com.android.library,您可以在其中集成原生代码,并从 Kotlin Multiplatform 库项目中使用该独立库。

  • BuildConfig

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