إعداد المكوّن الإضافي لمكتبة Android Gradle في KMP

المكوّن الإضافي com.android.kotlin.multiplatform.library لنظام Gradle هو الأداة المتاحة رسميًا لإضافة هدف Android إلى وحدة مكتبة في Kotlin Multiplatform (KMP). فهي تسهّل عملية ضبط إعدادات المشاريع، وتحسِّن أداء عمليات الإنشاء، وتوفّر تكاملاً أفضل مع Android Studio.

تم إيقاف الطريقة السابقة نهائيًا واستبدالها بالمكوّن الإضافي، الذي يُشار إليه أيضًا باسم المكوّن الإضافي Android-KMP. لن يكون بإمكانك مواصلة استخدام إضافة com.android.library KMP، ولن تستفيد من التحديثات والتحسينات المستقبلية.

لتطبيق هذا المكوّن الإضافي، يُرجى الرجوع إلى قسم تطبيق المكوّن الإضافي Android-KMP. إذا كنت بحاجة إلى نقل البيانات من واجهات برمجة التطبيقات القديمة، يُرجى الاطّلاع على دليل نقل البيانات.

الميزات والاختلافات الرئيسية

تم تصميم المكوّن الإضافي Android-KMP خصيصًا لمشاريع KMP، ويختلف عن المكوّن الإضافي com.android.library العادي في عدة جوانب رئيسية:

  • بنية الإصدار الفردي: تستخدم الإضافة إصدارًا واحدًا، ما يؤدي إلى إزالة التوافق مع نكهات المنتجات وأنواع الإصدارات، ما يسهّل عملية الإعداد ويحسّن أداء الإصدار.

  • محسَّن لمنصّة Kotlin المتعدّدة: تم تصميم المكوّن الإضافي لمكتبات KMP، مع التركيز على رموز Kotlin البرمجية المشتركة وإمكانية التشغيل التفاعلي، مع إغفال إتاحة الإصدارات الأصلية الخاصة بنظام Android وAIDL وRenderScript.

  • الاختبارات غير مفعَّلة تلقائيًا: يتم إيقاف كل من اختبارات الوحدات والاختبارات على الأجهزة (الاختبارات الآلية) تلقائيًا لتحسين سرعة الإنشاء. يمكنك تفعيلها إذا لزم الأمر.

  • لا توجد إضافة Android من المستوى الأعلى: تتم معالجة الإعدادات باستخدام كتلة androidLibrary ضمن لغة DSL الخاصة بمنصة KMP في Gradle، ما يحافظ على بنية متسقة لمشاريع 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، يجب ضبط مشروعك على الحد الأدنى من الإصدارات التالية أو إصدار أحدث:

  • المكوّن الإضافي لنظام Gradle المتوافق مع Android (AGP): الإصدار 8.10.0
  • المكوّن الإضافي لنظام Gradle المتوافق مع Kotlin (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.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 الموجود في الدليل الجذر لمشروعك. أضِف أسماء المكوّنات الإضافية البديلة إلى الحظر plugins باستخدام apply false. ويتيح ذلك استخدام أسماء مستعارة للمكوّن الإضافي في جميع المشاريع الفرعية بدون تطبيق منطق المكوّن الإضافي على المشروع الجذر نفسه.

    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 افتح ملف build.gradle.kts في وحدة مكتبة KMP وطبِّق المكوّن الإضافي في أعلى الملف ضمن كتلة 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. ضبط هدف KMP لنظام التشغيل Android اضبط حزمة Kotlin Multiplatform (kotlin) لتحديد هدف Android. ضِمن كتلة kotlin، حدِّد هدف Android باستخدام androidLibrary:

    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. بالإضافة إلى مجموعة المصادر الرئيسية، هناك مجموعتان من مصادر الاختبار يتم إنشاؤهما عند الطلب، وهما 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")
        }
    }
}

تحتوي مجموعات المصادر على عمليات تجميع متوافقة مع 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 {
  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

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، تم إنشاء مجموعتَي المصادر test وandroidTest تلقائيًا. يمكنك ضبط سلوكها داخل كتلة android، وعادةً ما تستخدم لغة 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 {
  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 تلقائيًا. تم ضبط هدف 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 متاحة للتفاعل مع عناصر إنشاء التطبيق آليًا. على الرغم من أنّ معظم واجهة برمجة التطبيقات 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.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 ضمن صيغة معيّنة لتحديد ترتيب البحث.

يُرجى الاطّلاع على حلّ أخطاء المطابقة للحصول على مزيد من التفاصيل حول استخدام واجهة برمجة التطبيقات.

مرجع واجهة برمجة التطبيقات الخاصة بالمكوّن الإضافي

يحتوي المكوّن الإضافي الجديد على مساحة مختلفة لواجهة برمجة التطبيقات عن com.android.library. للحصول على معلومات مفصّلة حول لغة DSL والواجهات الجديدة، راجِع مراجع واجهة برمجة التطبيقات: