為 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 專案結構的開發人員來說,這種命名慣例較不直覺。

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

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

必要條件

如要使用 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.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.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"
           }
    
           compilations.configureEach {
               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"
           }
    
           compilations.configureEach {
               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 {
    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.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 {
  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

3. 設定主機和裝置測試

新外掛程式的一項重大變更,就是預設會停用 Android 主機端 (單元) 和裝置端 (檢測設備) 測試。您必須明確選擇加入,才能建立測試來源集和設定,而舊版外掛程式會自動建立這些項目。

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

Android-KMP

在新外掛程式中,您可以在 kotlin.android 區塊內啟用及設定測試。這樣一來,設定會更加明確,且不會建立未使用的測試元件。test 來源集會變成 androidHostTest,而 androidTest 會變成 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 = "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 {
  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"
    }
  }
}

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 變體。不過,您可能依附於具有多種變體 (例如 com.android.libraryfree/paid 變種版本)。控管專案如何從該依附元件選取變體,是常見的需求。

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 用法,請參閱「解決比對錯誤」。

外掛程式 API 參考資料

新外掛程式的 API 介面與 com.android.library 不同。如要詳細瞭解新的 DSL 和介面,請參閱下列 API 參考資料: