پلاگین Android Gradle Library را برای KMP تنظیم کنید

افزونه‌ی com.android.kotlin.multiplatform.library Gradle ابزاری است که رسماً برای افزودن یک هدف اندروید به یک ماژول کتابخانه‌ی Kotlin Multiplatform (KMP) پشتیبانی می‌شود. این افزونه پیکربندی پروژه را ساده می‌کند، عملکرد ساخت را بهبود می‌بخشد و ادغام بهتری با اندروید استودیو ارائه می‌دهد.

استفاده از افزونه com.android.library برای توسعه KMP به APIهای افزونه Gradle اندروید بستگی دارد که منسوخ شده‌اند و در افزونه Gradle اندروید نسخه ۹.۰ و بالاتر (سه‌ماهه چهارم ۲۰۲۵) نیاز به انتخاب دارند . انتظار می‌رود این APIها در افزونه Gradle اندروید نسخه ۱۰.۰ (نیمه دوم ۲۰۲۶) حذف شوند .

برای اعمال این افزونه، به بخش اعمال افزونه Android-KMP مراجعه کنید. اگر نیاز به مهاجرت از APIهای قدیمی دارید، راهنمای مهاجرت را بررسی کنید.

ویژگی‌ها و تفاوت‌های کلیدی

افزونه Android-KMP به طور خاص برای پروژه‌های KMP طراحی شده است و از چندین جنبه کلیدی با افزونه استاندارد com.android.library متفاوت است:

  • معماری تک‌متغیره: این افزونه از یک نوع واحد استفاده می‌کند و پشتیبانی از طعم‌های محصول و انواع ساخت را حذف می‌کند، که پیکربندی را ساده کرده و عملکرد ساخت را افزایش می‌دهد.

  • بهینه شده برای KMP: این افزونه برای کتابخانه‌های KMP طراحی شده است و بر کد مشترک کاتلین و قابلیت همکاری تمرکز دارد و پشتیبانی از بیلدهای بومی مخصوص اندروید، AIDL و RenderScript را حذف کرده است.

  • تست‌ها به طور پیش‌فرض غیرفعال هستند: تست‌های واحد و دستگاه (ابزار دقیق) به طور پیش‌فرض غیرفعال هستند تا سرعت ساخت افزایش یابد. در صورت نیاز می‌توانید آنها را فعال کنید.

  • بدون افزونه سطح بالای اندروید: پیکربندی با یک بلوک androidLibrary در Gradle KMP DSL انجام می‌شود و ساختار پروژه KMP ثابتی را حفظ می‌کند. هیچ بلوک افزونه سطح بالای android وجود ندارد.

  • کامپایل جاوا به صورت اختیاری: کامپایل جاوا به صورت پیش‌فرض غیرفعال است. برای فعال کردن آن withJava() در بلوک androidLibrary استفاده کنید. این کار باعث بهبود زمان ساخت در مواقعی می‌شود که نیازی به کامپایل جاوا نیست.

مزایای افزونه کتابخانه Android-KMP

افزونه Android-KMP مزایای زیر را برای پروژه‌های KMP فراهم می‌کند:

  • بهبود عملکرد و پایداری ساخت: این نرم‌افزار برای سرعت ساخت بهینه و پایداری بیشتر در پروژه‌های KMP مهندسی شده است. تمرکز آن بر گردش‌های کاری KMP به فرآیند ساخت کارآمدتر و قابل اعتمادتر کمک می‌کند.

  • ادغام پیشرفته IDE: این قابلیت، تکمیل کد، ناوبری، اشکال‌زدایی و تجربه کلی توسعه‌دهنده را هنگام کار با کتابخانه‌های اندروید KMP بهبود می‌بخشد.

  • پیکربندی ساده‌شده پروژه: این افزونه با حذف پیچیدگی‌های خاص اندروید مانند build variants، پیکربندی پروژه‌های KMP را ساده می‌کند. این امر منجر به فایل‌های ساخت تمیزتر و قابل نگهداری‌تر می‌شود. پیش از این، استفاده از افزونه com.android.library در پروژه KMP می‌توانست نام‌های مجموعه منبع گیج‌کننده‌ای مانند androidAndroidTest ایجاد کند. این قرارداد نامگذاری برای توسعه‌دهندگانی که با ساختارهای استاندارد پروژه KMP آشنا بودند، کمتر قابل درک بود.

مشکلات شناخته‌شده در افزونه کتابخانه Android-KMP

اینها مشکلات شناخته‌شده‌ای هستند که ممکن است هنگام اعمال افزونه جدید com.android.kotlin.multiplatform.library رخ دهند:

پیش‌نیازها

برای استفاده از افزونه‌ی com.android.kotlin.multiplatform.library ، پروژه‌ی شما باید با حداقل نسخه‌های زیر یا بالاتر پیکربندی شود:

  • افزونه‌ی گریدل اندروید (AGP) : 8.10.0
  • افزونه کاتلین گریدل (KGP) : نسخه ۲.۰.۰

افزونه 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 اضافه کنید. این کار باعث می‌شود نام‌های مستعار افزونه بدون اعمال منطق افزونه به خود پروژه ریشه، برای همه زیرپروژه‌ها در دسترس باشند.

    کاتلین

    // 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. پیکربندی هدف KMP اندروید. بلوک چند پلتفرمی کاتلین ( kotlin ) را برای تعریف هدف اندروید پیکربندی کنید. درون بلوک kotlin ، هدف اندروید را با استفاده از androidLibrary مشخص کنید:

    کاتلین

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

    گرووی

    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 مهاجرت کنید.

۱. اعلان وابستگی‌ها

یک وظیفه رایج، اعلان وابستگی‌ها برای مجموعه‌های منبع مخصوص اندروید است. افزونه جدید، برخلاف بلوک dependencies عمومی که قبلاً استفاده می‌شد، مستلزم آن است که این وابستگی‌ها به طور صریح در بلوک sourceSets قرار گیرند.

اندروید-KMP

این افزونه جدید با گروه‌بندی وابستگی‌های اندروید در مجموعه منابع androidMain ، ساختار تمیزتری را ایجاد می‌کند. علاوه بر مجموعه منابع اصلی، دو مجموعه منبع آزمایشی نیز وجود دارد که بنا به تقاضا ایجاد می‌شوند: androidDeviceTest و androidHostTest (برای اطلاعات بیشتر ، تست‌های پیکربندی میزبان و دستگاه را بررسی کنید).

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

مجموعه‌های منبع، کامپایل‌های کاتلین متناظری به نام‌های main ، deviceTest و hostTest دارند. مجموعه‌های منبع و کامپایل‌ها را می‌توان در اسکریپت ساخت به صورت زیر پیکربندی کرد:

// build.gradle.kts

kotlin {
    androidLibrary {
        compilations.getByName("deviceTest") {
            kotlinOptions.languageVersion = "2.0"
        }
    }
}

افزونه قدیمی

با افزونه قدیمی، می‌توانستید وابستگی‌های مخصوص اندروید را در بلوک وابستگی‌های سطح بالا تعریف کنید، که گاهی اوقات در یک ماژول چند پلتفرمی می‌تواند گیج‌کننده باشد.

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

۲. فعال کردن منابع اندروید

پشتیبانی از منابع اندروید (پوشه‌های res ) به طور پیش‌فرض در افزونه جدید برای بهینه‌سازی عملکرد ساخت فعال نیست. شما باید برای استفاده از آنها تصمیم بگیرید. این تغییر کمک می‌کند تا پروژه‌هایی که به منابع مخصوص اندروید نیاز ندارند، تحت فشار سربار ساخت مرتبط قرار نگیرند.

اندروید-KMP

شما باید صراحتاً پردازش منابع اندروید را فعال کنید. منابع باید در 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

افزونه قدیمی

پردازش منابع به طور پیش‌فرض فعال بود. شما می‌توانستید بلافاصله یک دایرکتوری 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

۳. پیکربندی تست‌های میزبان و دستگاه

یک تغییر قابل توجه در افزونه جدید این است که تست‌های سمت میزبان (واحد) و سمت دستگاه (ابزار) اندروید به طور پیش‌فرض غیرفعال هستند . شما باید صریحاً ایجاد مجموعه‌ها و پیکربندی‌های منبع تست را انتخاب کنید، در حالی که افزونه قدیمی آنها را به طور خودکار ایجاد می‌کرد.

این مدل انتخابی به شما کمک می‌کند تا مطمئن شوید که پروژه شما ناب باقی می‌ماند و فقط شامل منطق ساخت و مجموعه‌های منبعی است که به طور فعال از آنها استفاده می‌کنید.

اندروید-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 ، مجموعه‌های منبع test و androidTest به طور پیش‌فرض ایجاد می‌شدند. شما می‌توانید رفتار آنها را درون بلوک 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

۴. فعال کردن کامپایل سورس جاوا

اگر کتابخانه KMP شما نیاز به کامپایل منابع جاوا برای هدف اندروید خود دارد، باید صریحاً این قابلیت را با افزونه جدید فعال کنید. توجه داشته باشید که این کار کامپایل را برای فایل‌های جاوا که مستقیماً در پروژه شما قرار دارند فعال می‌کند، نه برای وابستگی‌های آن. روش تنظیم نسخه هدف JVM کامپایلر جاوا و کاتلین نیز تغییر می‌کند.

اندروید-KMP

شما باید با فراخوانی withJava() کامپایل جاوا را انتخاب کنید. هدف JVM اکنون مستقیماً درون بلوک kotlin { androidLibrary {} } پیکربندی شده است تا تنظیمات یکپارچه‌تری داشته باشید. تنظیم jvmTarget در اینجا برای کامپایل کاتلین و جاوا برای هدف اندروید اعمال می‌شود.

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

افزونه قدیمی

کامپایل جاوا به طور پیش‌فرض فعال بود. هدف JVM برای هر دو منبع جاوا و کاتلین در بلوک اندروید با استفاده از compileOptions تنظیم شده بود.

// build.gradle.kts

android {
  // ...
  compileOptions {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
  }
}

kotlin {
  androidTarget {
    compilations.all {
      kotlinOptions.jvmTarget = "1.8"
    }
  }
}

۵. تعامل با انواع ساخت با استفاده از androidComponents

افزونه androidComponents هنوز برای تعامل با مصنوعات ساخت از طریق برنامه‌نویسی در دسترس است. در حالی که بخش زیادی از API Variant بدون تغییر باقی مانده است، رابط کاربری جدید AndroidKotlinMultiplatformVariant محدودتر است زیرا این افزونه فقط یک نوع واحد تولید می‌کند.

در نتیجه، ویژگی‌های مربوط به انواع ساخت و طعم‌های محصول دیگر در شیء متغیر موجود نیستند.

اندروید-KMP

بلوک onVariants اکنون روی یک نوع تکرار می‌شود. شما هنوز می‌توانید به ویژگی‌های رایج مانند name و artifacts دسترسی داشته باشید، اما نمی‌توانید به ویژگی‌های build-type-specific دسترسی داشته باشید.

// build.gradle.kts

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

افزونه قدیمی

با وجود چندین نوع، می‌توانید به ویژگی‌های خاص نوع ساخت برای پیکربندی وظایف دسترسی پیدا کنید.

// build.gradle.kts

androidComponents {
  onVariants(selector().withBuildType("release")) { variant ->
    // ...
  }
}

۶. انواع وابستگی‌های کتابخانه اندروید را انتخاب کنید

کتابخانه KMP شما یک نوع واحد برای اندروید تولید می‌کند. با این حال، ممکن است به یک کتابخانه استاندارد اندروید ( com.android.library ) وابسته باشید که انواع مختلفی دارد (مثلاً نسخه‌های free/paid محصول). کنترل نحوه انتخاب یک نوع از آن وابستگی توسط پروژه شما یک نیاز رایج است.

اندروید-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 برای ارائه یک flavor پیش‌فرض برای بُعدی که کتابخانه شما آن را نداشته است، یا matchingFallbacks درون یک flavor خاص برای تعریف ترتیب جستجو می‌شود.

برای اطلاعات بیشتر در مورد کاربرد API، به بخش «رفع خطاهای تطبیق» مراجعه کنید.

مرجع API افزونه

افزونه جدید سطح API متفاوتی نسبت به com.android.library دارد. برای اطلاعات دقیق در مورد DSL و رابط‌های جدید، به منابع API مراجعه کنید:

{% کلمه به کلمه %} {% فعل کمکی %} {% کلمه به کلمه %} {% فعل کمکی %}