為 KMP 設定 Android Gradle 程式庫外掛程式

com.android.kotlin.multiplatform.library Gradle 外掛程式是官方支援的工具,可將 Android 目標新增至 Kotlin Multiplatform (KMP) 程式庫模組。可簡化專案設定、提升建構效能,並與 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 外掛程式在幾個重要方面有所不同:

  • 單一變數架構:外掛程式會使用單一變數,移除對變種版本和建構類型的支援,簡化設定並提升建構效能。

  • 專為 KMP 最佳化:這個外掛程式專為 KMP 程式庫設計,著重於共用的 Kotlin 程式碼和互通性,省略對 Android 專用原生建構作業、AIDL 和 RenderScript 的支援。

  • 預設停用測試:為提升建構速度,單元和裝置 (檢測設備) 測試預設都會停用。您可以視需要啟用這些功能。

  • 沒有頂層 Android 擴充功能:設定是在 Gradle KMP DSL 內的 androidLibrary 區塊中處理,可維持一致的 KMP 專案結構。沒有頂層 android 擴充功能區塊。

  • 選擇啟用 Java 編譯:Java 編譯功能預設為停用。請在 androidLibrary 區塊中使用 withJava() 啟用這項功能。這樣一來,就不必進行 Java 編譯,可縮短建構時間。

Android-KMP 程式庫外掛程式的優點

Android-KMP 外掛程式可為 KMP 專案提供下列優點:

  • 提升建構效能和穩定性:專為最佳化建構速度而設計,可提升 KMP 專案的穩定性。著重於 KMP 工作流程,有助於提升建構程序的效率和可靠性。

  • 強化 IDE 整合:使用 KMP Android 程式庫時,可提供更優質的程式碼完成、導覽、偵錯和整體開發人員體驗。

  • 簡化專案設定:這個外掛程式可移除建構變數等 Android 專屬的複雜項目,簡化 KMP 專案的設定。這會產生更乾淨且更容易維護的建構檔案。先前在 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.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 程式庫模組建構檔案中套用外掛程式。開啟 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.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 資源

為提升建構效能,新版外掛程式預設不會啟用 Android 資源 (res 資料夾) 支援功能。您必須選擇採用,才能使用這些功能。這項變更可確保不需要 Android 專屬資源的專案,不會受到相關建構負擔的影響。

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 主機端 (單元) 和裝置端 (檢測設備) 測試。您必須明確選擇建立測試來源集和設定,舊版外掛程式則會自動建立這些項目。

這個選擇加入模式有助於確保專案保持精簡,只包含您主動使用的建構邏輯和來源集。

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 = "ANDROIDX_TEST_ORCHESTRATOR"
    }
  }
}

// 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 = "ANDROIDX_TEST_ORCHESTRATOR"
  }
}

// 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 與建構變數互動

您仍可使用 androidComponents 擴充功能,以程式輔助方式與建構構件互動。雖然 Variant API 的大部分內容都維持不變,但由於外掛程式只會產生單一變體,因此新版 AndroidKotlinMultiplatformVariant 介面的限制較多。

因此,與建構類型和變種版本相關的屬性不再適用於變體物件。

Android-KMP

onVariants 區塊現在會疊代單一變數。您仍可存取 nameartifacts 等常見屬性,但無法存取建構類型專屬屬性。

// build.gradle.kts

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

舊版外掛程式

有了多個變體,您就能存取建構類型專屬的屬性,以設定工作。

// 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 外掛程式時,這會成為一項挑戰,因為該外掛程式會移除用於區隔開發依附元件與發布程式碼的建構類型架構。

Android-KMP

如要只為本機開發和測試新增依附元件,請將依附元件直接新增至主要 Android 編譯的執行階段類別路徑設定 (位於頂層 dependencies 區塊中)。這有助於確保依附元件在執行階段可用 (例如適用於 Compose 預覽等工具),但不會成為程式庫的編譯類別路徑或發布的 API。

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

舊版外掛程式

針對 Android 目標使用 com.android.library 外掛程式的 Kotlin Multiplatform 專案,應使用 debugImplementation 設定,將依附元件範圍限定為偵錯建構類型,並防止依附元件納入消費者使用的程式庫發布變數。

// 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 介面與 com.android.library 不同。如要詳細瞭解新的 DSL 和介面,請參閱下列 API 參考資料:

Android-KMP 程式庫外掛程式的已知問題

套用新版 com.android.kotlin.multiplatform.library 外掛程式時,可能會發生下列已知問題:

不支援的功能

與使用 com.android.library 外掛程式整合 KMP 相比,com.android.kotlin.multiplatform.library 外掛程式缺少下列功能:

  • 資料繫結和檢視區塊繫結

    這些是 Android 專屬的 UI 架構功能,與 Android View 系統和 XML 版面配置緊密結合。在新版 Android-KMP 程式庫外掛程式中,我們建議使用 Compose Multiplatform 等多平台架構處理 UI。資料繫結和檢視區塊繫結是最終 Android 應用程式的實作詳細資料,而非可共用的程式庫。

  • 原生建構支援

    新外掛程式的重點是為 Android 目標產生標準 AAR。Kotlin Multiplatform 會直接透過本身的目標平台 (例如 androidNativeArm64androidNativeX86) 和 C 互通功能,處理 Kotlin Multiplatform 中的原生程式碼整合。如需納入原生 C/C++ 程式碼,您應將其定義為通用或原生來源集的一部分,並在 kotlin 區塊中設定 C 互通性,而非使用 Android 專屬的 externalNativeBuild 機制。

    或者,如果您需要原生建構支援,建議您建立獨立的 com.android.library,整合原生程式碼,並從 Kotlin Multiplatform 程式庫專案使用獨立程式庫。

  • BuildConfig 類別

    BuildConfig 功能在多變數環境中特別實用。 由於新的 Kotlin Multiplatform 程式庫外掛程式與變體無關,且不支援建構類型和產品風味,因此未實作這項功能。建議您改用 BuildKonfig外掛程式 或類似的社群解決方案,為所有目標產生中繼資料。