Настройка плагина Android Gradle Library для KMP

Плагин Gradle com.android.kotlin.multiplatform.library — это официально поддерживаемый инструмент для добавления целевого объекта Android в модуль библиотеки Kotlin Multiplatform (KMP). Он упрощает настройку проекта, повышает производительность сборки и обеспечивает лучшую интеграцию с Android Studio.

Использование плагина com.android.library для разработки KMP зависит от API плагина Android Gradle, которые устарели и требуют дополнительной активации в плагине Android Gradle версии 9.0 и выше (IV квартал 2025 г.). Ожидается, что эти API будут удалены в плагине Android Gradle версии 10.0 (вторая половина 2026 г.).

Чтобы применить этот плагин, обратитесь к разделу «Применение плагина Android-KMP» . Если вам необходимо перейти с устаревших API, ознакомьтесь с руководством по миграции .

Основные особенности и отличия

Плагин Android-KMP разработан специально для проектов KMP и отличается от стандартного плагина com.android.library по нескольким ключевым параметрам:

  • Архитектура с одним вариантом: плагин использует один вариант, исключая поддержку вариантов продукта и типов сборки, что упрощает настройку и повышает производительность сборки.

  • Оптимизировано для KMP: плагин разработан для библиотек KMP, ориентирован на общий код Kotlin и совместимость, исключая поддержку нативных сборок, специфичных для Android, AIDL и RenderScript.

  • Тесты отключены по умолчанию: как модульные, так и инструментальные (тесты устройств) тесты отключены по умолчанию для повышения скорости сборки. При необходимости вы можете включить их.

  • Отсутствует блок расширения Android верхнего уровня: конфигурация осуществляется с помощью блока androidLibrary в рамках Gradle KMP DSL, что обеспечивает согласованную структуру проекта KMP. Блок расширения android верхнего уровня отсутствует.

  • Включение компиляции Java: компиляция Java отключена по умолчанию. Используйте withJava() в блоке androidLibrary , чтобы включить её. Это сокращает время сборки, когда компиляция Java не требуется.

Преимущества плагина библиотеки Android-KMP

Плагин Android-KMP предоставляет следующие преимущества для проектов KMP:

  • Улучшенная производительность и стабильность сборки: система разработана для оптимизации скорости сборки и повышения стабильности в проектах KMP. Ориентация на рабочие процессы KMP способствует более эффективному и надежному процессу сборки.

  • Улучшенная интеграция с IDE: обеспечивает более удобное автозавершение кода, навигацию, отладку и в целом улучшает пользовательский опыт при работе с библиотеками KMP для Android.

  • Упрощенная конфигурация проекта: плагин упрощает конфигурацию проектов KMP, устраняя сложности, специфичные для Android, такие как варианты сборки. Это приводит к созданию более чистых и удобных в сопровождении файлов сборки. Ранее использование плагина com.android.library в проекте KMP могло приводить к появлению запутанных имен наборов исходных файлов, таких как androidAndroidTest . Это соглашение об именовании было менее интуитивно понятным для разработчиков, знакомых со стандартной структурой проектов KMP.

Предварительные требования

Для использования плагина com.android.kotlin.multiplatform.library ваш проект должен быть настроен с использованием следующих минимальных версий или выше:

  • Android Gradle Plugin (AGP) : 8.10.0
  • Kotlin Gradle Plugin (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 расположенный в корневом каталоге вашего проекта. Добавьте псевдонимы плагинов в блок plugins , используя apply false . Это сделает псевдонимы плагинов доступными для всех подпроектов без применения логики плагина к самому корневому проекту.

    Котлин

    // 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
    }

    Классный

    // 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.gradle.kts в вашем модуле библиотеки KMP и примените плагин в верхней части файла внутри блока plugins :

    Котлин

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

    Классный

    // 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, используя androidLibrary :

    Котлин

    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.) ...
    }

    Классный

    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 . В дополнение к основному набору исходных кодов существуют два набора исходных кодов для тестов, которые создаются по запросу: androidDeviceTest и androidHostTest (подробнее см. в разделе « Настройка тестов хоста и устройства »).

// 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 с именами main , deviceTest и hostTest . Наборы исходных файлов и компиляции можно настроить в скрипте сборки следующим образом:

// 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

Устаревший плагин

Обработка ресурсов была включена по умолчанию. Вы могли сразу же добавить каталог res в src/main и начать добавлять 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. Настройка тестов хоста и устройства

Существенное изменение в новом плагине заключается в том, что модульные (unit) и инструментальные (instrumented) тесты Android по умолчанию отключены . Для создания наборов исходных файлов и конфигураций тестов необходимо явно включить эту функцию, тогда как старый плагин создавал их автоматически.

Эта модель с добровольным участием помогает убедиться в том, что ваш проект остается компактным и включает только ту логику сборки и наборы исходных кодов, которые вы активно используете.

Android-KMP

В новом плагине включение и настройка тестов осуществляется внутри блока kotlin.androidLibrary . Это делает настройку более явной и позволяет избежать создания неиспользуемых тестовых компонентов. Набор источников test становится androidHostTest , а androidTestandroidDeviceTest .

// 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 наборы исходных файлов test и androidTest создавались по умолчанию. Их поведение настраивалось внутри блока android , как правило, с помощью DSL testOptions .

// 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 требуется компилировать исходные коды Java для целевой платформы Android, необходимо явно включить эту функцию с помощью нового плагина. Обратите внимание, что это включает компиляцию для файлов Java, расположенных непосредственно в вашем проекте, а не для его зависимостей. Также изменяется способ установки целевой версии JVM для компиляторов Java и Kotlin.

Android-KMP

Необходимо включить компиляцию на Java, вызвав метод withJava() . Теперь целевая платформа JVM настраивается непосредственно внутри блока kotlin { androidLibrary {} } для более унифицированной конфигурации. Установка jvmTarget здесь применяется как к компиляции на Kotlin, так и на Java для целевой платформы Android.

// 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 была включена по умолчанию. Целевая среда JVM для исходных кодов Java и Kotlin была задана в блоке 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 по-прежнему доступно для программного взаимодействия с артефактами сборки. Хотя большая часть API Variant осталась прежней, новый интерфейс AndroidKotlinMultiplatformVariant более ограничен, поскольку плагин создает только один вариант.

Следовательно, свойства, связанные с типами сборки и вариантами продукта, больше недоступны в объекте варианта.

Android-KMP

Блок onVariants теперь перебирает один вариант. Вы по-прежнему можете получить доступ к общим свойствам, таким как name и artifacts , но не к свойствам, специфичным для типа сборки.

// 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. Создайте предварительные зависимости.

Обычно нам нужно, чтобы определенные библиотеки были привязаны к нашей локальной среде разработки, чтобы предотвратить проникновение внутренних инструментов в итоговый опубликованный артефакт. С новым плагином KMP для Android это становится проблемой, поскольку он отменяет архитектуру типов сборки, используемую для разделения зависимостей разработки от кода релиза.

Android-KMP

Чтобы добавить зависимость только для локальной разработки и тестирования, добавьте её непосредственно в конфигурацию classpath во время выполнения (в блоке dependencies верхнего уровня) основной компиляции Android. Это поможет гарантировать, что зависимость будет доступна во время выполнения (например, для таких инструментов, как Compose Preview ), но не будет частью classpath компиляции или опубликованного API вашей библиотеки.

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

Устаревший плагин

В проектах Kotlin Multiplatform, использующих плагин com.android.library для целевой платформы Android, следует использовать конфигурацию debugImplementation , которая ограничивает зависимость типом сборки debug и предотвращает её включение в вариант сборки release библиотеки, используемый потребителями.

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

8. Настройте целевую среду JVM для KMP Android.

Плагин KMP для Android устанавливает целевую платформу JVM с помощью androidLibrary.compilerOptions.jvmTarget , что применимо как к Java, так и к Kotlin, упрощая конфигурацию по сравнению с отдельными блоками compileOptions и kotlinOptions в проектах, полностью посвященных Android.

Android-KMP

При работе с проектом Kotlin Multiplatform (KMP), включающим целевую платформу Android, существует несколько способов настройки версии JVM для компиляторов Kotlin и Java. Понимание области действия и иерархии этих конфигураций является ключом к управлению совместимостью байт-кода вашего проекта.

Вот три основных способа установки целевой платформы JVM, упорядоченные от наименьшего к наибольшему приоритету. Значения целевой платформы JVM с более высоким приоритетом применяются к меньшему подмножеству настроенных целевых платформ и переопределяют значения с более низким приоритетом, что означает, что вы можете устанавливать разные версии JVM для разных целевых платформ и компиляций внутри целевых платформ в вашем проекте.

Использование инструментария Kotlin (с самым низким приоритетом).

Наиболее универсальный способ задать целевую платформу JVM — указать цепочку инструментов в блоке kotlin файла build.gradle.kts . Такой подход устанавливает целевую платформу как для компиляции Kotlin, так и для Java для всех целевых платформ JVM в вашем проекте, включая Android.

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

Эта конфигурация позволяет kotlinc и javac использовать JVM версии 21. Это отличный способ установить согласованную базовую версию для всего вашего проекта.

Использование параметров компилятора на уровне целевой платформы Android (средний приоритет)

В блоке android можно указать целевую JVM специально для Android KMP. Этот параметр переопределяет конфигурацию jvmToolchain , применяемую ко всему проекту, и распространяется на все компиляции Android.

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

В этом случае, даже если для параметра jvmToolchain установлена ​​другая версия, код Kotlin и Java для целевой платформы Android будет скомпилирован для целевой JVM 11.

Использование параметров компиляции на уровне компиляции (наивысший приоритет)

Для наиболее точного контроля можно настроить параметры компилятора для каждой компиляции отдельно (например, только для androidMain или androidHostTest ). Это полезно, если для конкретной компиляции требуется использовать другую версию JVM. Этот параметр переопределяет как параметры инструментария Kotlin, так и параметры на уровне целевой платформы Android.

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

Эта конфигурация помогает гарантировать, что все компиляции в целевой среде Android используют JVM 11, обеспечивая точный контроль.

Устаревший плагин

В проекте KMP, использующем стандартный плагин библиотеки Android ( com.android.library ), конфигурация немного отличается от конфигурации при использовании плагина KMP Android (но концептуально схожа).

Использование инструментария Kotlin

Метод kotlin.jvmToolchain() работает аналогично, устанавливая sourceCompatibility и targetCompatibility для Java и jvmTarget для Kotlin. Мы рекомендуем использовать именно этот подход.

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

compileOptions и kotlinOptions

Если вы не используете инструментарий Kotlin, вам необходимо настроить целевые платформы JVM, используя отдельные блоки для Java и Kotlin.

// 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 :

Неподдерживаемые функции

При сравнении с интеграцией KMP с плагином com.android.library , в плагине com.android.kotlin.multiplatform.library отсутствуют следующие функции:

  • Привязка данных и привязка представления

    Это специфические для Android особенности пользовательского интерфейса, тесно связанные с системой представлений Android и XML-макетами. В новом плагине библиотеки Android-KMP мы рекомендуем использовать для обработки пользовательского интерфейса многоплатформенный фреймворк, такой как Compose Multiplatform . Привязка данных и привязка представлений считаются деталями реализации конечного приложения Android, а не общей библиотекой.

  • Поддержка нативной сборки

    Новый плагин ориентирован на создание стандартного AAR-файла для целевой платформы Android. Интеграция нативного кода в Kotlin Multiplatform осуществляется непосредственно собственными нативными целевыми платформами KMP (такими как androidNativeArm64 и androidNativeX86 ) и его возможностями взаимодействия с C. Если вам необходимо включить нативный код C/C++, следует определить его как часть общего или нативного набора исходных файлов и настроить взаимодействие с C внутри блока kotlin , а не использовать механизм externalNativeBuild , специфичный для Android.

    В качестве альтернативы, если вам необходима поддержка нативной сборки, мы рекомендуем создать отдельный автономный com.android.library , куда вы сможете интегрировать нативный код и использовать эту автономную библиотеку из вашего проекта библиотеки Kotlin Multiplatform.

  • Класс BuildConfig

    Функция BuildConfig наиболее полезна в многовариантных средах. Поскольку новый плагин библиотеки Kotlin Multiplatform не зависит от варианта и не поддерживает типы сборки и варианты продукта, эта функция не реализована. В качестве альтернативы мы рекомендуем использовать плагин BuildKonfig или аналогичные решения от сообщества для генерации метаданных для всех целей.

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %}