KMP 用の Android Gradle ライブラリ プラグインを設定する

com.android.kotlin.multiplatform.library Gradle プラグインは、Kotlin Multiplatform(KMP)ライブラリ モジュールに Android ターゲットを追加するために公式にサポートされているツールです。プロジェクト構成が簡素化され、ビルド パフォーマンスが向上し、Android Studio との統合が改善されます。

以前のアプローチは非推奨となり、プラグイン(Android-KMP プラグインとも呼ばれます)が推奨されるようになりました。KMP 用の com.android.library プラグインを継続して使用しても、JetBrains によるサポートは終了し、今後のアップデートや改善のメリットは得られなくなります。

このプラグインを適用するには、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 プラグインを適用する

既存の KMP ライブラリ モジュールに Android-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.12.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 マルチプラットフォーム ブロック(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 固有のソースセットの依存関係を宣言することです。新しいプラグインでは、以前使用されていた一般的な dependencies ブロックとは異なり、これらを sourceSets ブロック内に明示的に配置する必要があります。

Android-KMP

新しいプラグインは、Android の依存関係を androidMain ソースセット内にグループ化することで、よりクリーンな構造を促進します。メインのソースセットに加えて、オンデマンドで作成される 2 つのテストソースセット(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")
        }
    }
}

ソースセットには、maindeviceTesthostTest という名前の対応する Kotlin コンパイルがあります。ソースセットとコンパイルは、次のようにビルドスクリプトで構成できます。

// 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/mainres ディレクトリをすぐに追加して、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 に、androidTestandroidDeviceTest になります。

// 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 のソースセットがデフォルトで作成されました。通常は testOptions DSL を使用して、android ブロック内で動作を構成します。

// 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 ターゲットは、compileOptions を使用して android ブロックで設定されていました。

// 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 の大部分は変更されていませんが、プラグインで生成されるバリアントが 1 つのみであるため、新しい 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 リファレンスをご覧ください。