الاعتماد المتبادل بين الأدوات والمكتبات

تبعيات التصميم هي مكوّنات خارجية مطلوبة لإنشاء مشروعك بنجاح. وقد يعتمد التصميم على المكتبات والمكوّنات الإضافية والمشاريع الفرعية وحزمة تطوير البرامج (SDK) لنظام التشغيل Android وأدوات مثل برامج التحويل البرمجي Kotlin وJava وبيئات التطوير، مثل Android Studio وGradle.

ويمكن أن تتطلّب كل تبعية تبعيات أخرى. ونُطلق على هذه التبعيات اسم التبعيات الانتقالية، ويمكن أن تزيد بسرعة من إجمالي التبعيات المستخدَمة في تطبيقك. عندما تريد ترقية أحد العناصر المُستخدَمة، سواء كانت مكتبة أو أداة أو حزمة تطوير برامج (SDK) لنظام التشغيل Android، يمكن أن تؤدي هذه الترقية إلى ترقية العديد من العناصر المُستخدَمة الأخرى.

وغالبًا ما لن يسبب هذا الأمر أي مشاكل، حيث تتّبع العديد من المكتبات نظامًا يُعرف باسم تحديد الإصدارات الدلالية. تقيد هذه المكتبات أنواع التغييرات التي تقوم بها لتوفير التوافق مع إصداراتها المنخفضة.

يتّبع التنسيق الدلالي للإصدار تنسيق major.minor.patch. على سبيل المثال، في رقم الإصدار 4.8.3، يشير الرقم 4 إلى الإصدار major، ويشير الرقم 8 إلى الإصدار minor، ويشير الرقم 3 إلى الإصدار patch. عندما يتغير الجزء major، قد تتضمن المكتبة تغييرات قد تؤدي إلى أعطال في واجهة برمجة التطبيقات أو السلوك. ويمكن أن يؤثر ذلك في سلوك الإصدار أو التطبيق.

عند تغيير الجزء minor (الميزات الجديدة) أو patch (إصلاح الأخطاء)، يخبرك مطوِّرو المكتبة بأنّ المكتبة لا تزال متوافقة ومن المفترض ألا تؤثر في تطبيقك.

من المهم الانتباه إلى هذه التغييرات، ويمكن أن تساعدك عدة أدوات ترقية التبعيات.

العلاقات في إصدارك

تحتوي إصدارات Android على علاقات بين ما يلي:

  • رمز المصدر: وهو الرمز والموارد التي يمكنك التحكّم فيها
  • مكتبات أو وحدات خارجية يتضمنها مشروعك ومشاريعك الفرعية عند الإنشاء
  • الأدوات: برامج التحويل البرمجي والمكونات الإضافية وحِزم SDK التي تُحوّل المصدر إلى تطبيق أو مكتبة
إنشاء التبعيات وعلاقاتها
الشكل 1. بناء العلاقات

رمز مصدر

الرمز المصدر هو رمز Kotlin أو Java الذي تكتبه في تطبيقك أو مكتبتك. (للاطّلاع على تفاصيل عن استخدام C++، يُرجى الاطّلاع على Android NDK).

يعتمد الرمز المصدر على المكتبات (بما في ذلك مكتبات وقت التشغيل لكل من Kotlin وJava) وحزمة تطوير البرامج (SDK) لنظام التشغيل Android، ويتطلّب استخدام مُجمِّع Kotlin أو Java المقابل.

يتضمّن بعض الرموز البرمجية المصدرية تعليقات توضيحية تتطلّب معالجة إضافية. على سبيل المثال، إذا كنت تكتب رمز Jetpack Compose، يمكنك إضافة تعليقات توضيحية مثل @Composable التي يجب معالجتها بواسطة مكوّن Compose Kotlin compiler المكوّن. يمكن معالجة التعليقات التوضيحية الأخرى باستخدام معالج رمز Kotlin (KSP) أو أدوات معالجة التعليقات التوضيحية منفصلة.

العناصر التابعة للمكتبة

تحتوي المكتبات على رمز برمجي ثنائي يتم استرجاعه كجزء من تطبيقك. يمكن أن يكون ذلك ملف JAR لبرنامج Java أو مكتبة Android (AAR) أو مشروعًا فرعيًا في حِزمك. تتبع العديد من المكتبات الإصدار الدلالي، الذي يمكن أن يساعدك في معرفة متى تظل متوافقة (أو لا تظل) متوافقة عند الترقية.

قد تعتمد المكتبات على مكتبات أخرى لإعادة استخدامها، ما يُعرف باسم التبعية غير المباشرة. وهذا يقلل من التبعيات التي يجب عليك إدارتها بشكل صريح؛ حيث تحدد التبعيات التي تستخدمها مباشرة، وتسحبها Gradle إلى جانب تلك التبعيات المنتقلة. اعلم أنه أثناء ترقية تبعياتك المباشرة، قد تؤدي إلى ترقية تلك التبعيات المتعدة.

في بعض الأحيان، قد تتطلّب المكتبة الحد الأدنى من إصدارات حزمة تطوير البرامج (SDK) لنظام التشغيل Android في وقت التشغيل (minSdk) أو وقت الترجمة (compileSdk). ويُعدّ ذلك ضروريًا عندما تستخدم المكتبة وظائف مضمّنة في حزمة تطوير البرامج (SDK) لنظام التشغيل Android أو واجهات برمجة التطبيقات JDK المقدَّمة. minSdk الفعّال لتطبيقك هو أعلى minSdk يطلبها تطبيقك وجميع مكتباته المباشرة وغير المباشرة.

قد يتطلّب استخدام بعض المكتبات استخدام مكوّن إضافي محدّد من Gradle. غالبًا ما تُثبِّت هذه المكونات الإضافية المساعِدة معالجات رموز Kotlin أو معالجات التعليقات التوضيحية الأخرى التي تُنشئ رمزًا أو تعدّل عملية تجميع المصدر لتسهيل استخدامك لميزات المكتبة. على سبيل المثال، يتضمّن Jetpack Room تعليقات توضيحية ومكتبة KSP تحوّلها إلى رمز تم إنشاؤه لاسترداد البيانات وتعديلها في قاعدة بيانات. يتطلّب Jetpack Compose من المكوّن الإضافي لبرنامج Composer لتعديل الدوال التي تتضمّن تعليقات توضيحية لإدارة طريقة وتوقيت إعادة تشغيل هذه الدالة.

الأدوات

Gradle

Gradle هي أداة التصميم التي تقرأ ملفات التصميم وتنشئ التطبيق أو المكتبة، كما تعرض أيضًا واجهة برمجة تطبيقات للمكونات الإضافية لتوسيع قدراتها. تشغّل Gradle عمليات متعددة على جهاز افتراضي واحد أو أكثر من أجهزة Java، وتستدعي المكونات الإضافية لـ Java أدوات Java داخل JDK.

مكوّنات Gradle الإضافية

تعمل مكونات Gradle الإضافية على توسيع Gradle من خلال تحديد مهام وتهيئة جديدة. يؤدي تطبيق مكوِّن إضافي على تصميمك إلى تفعيل إمكانات تصميم معيّنة، يتم ضبطها كبيانات في النصوص البرمجية للإصدار. بالنسبة إلى عمليات إنشاء تطبيقات Android، فإنّ أهم مكوّن إضافي في Gradle هو المكوّن الإضافي لنظام Gradle المتوافق مع Android (AGP).

محولات برمجية

يحوّل مُجمِّع Kotlin أو Java رمز المصدر إلى رمز برمجي ثنائي قابل للتنفيذ. يعرِض مُجمِّع Kotlin واجهة برمجة تطبيقات للمكوّنات الإضافية تتيح إجراء التحليل الخارجي وإنشاء الرموز البرمجية داخل المُجمِّع مباشرةً، والوصول إلى بنية الرمز البرمجي المفسَّر.

المكوّنات الإضافية لبرامج التحويل البرمجي

تُجري مكوّنات الترميز الإضافية عمليات التحليل وإنشاء الرموز البرمجية داخل مكوّن الترميز Kotlin أثناء تحليل مكوّن الترميز Kotlin لرمزك البرمجي، ويتم تثبيتها عند تطبيق مكوّنات Gradle الإضافية على عملية الإنشاء.

Android SDK

تحتوي حزمة تطوير البرامج (SDK) لنظام التشغيل Android على نظام Android وواجهات برمجة تطبيقات Java لإصدار محدّد من Android وأدواته المقابلة. تساعدك هذه الأدوات في إدارة حزمة تطوير البرامج (SDK) وإنشاء التطبيقات والتواصل مع أجهزة Android ومحاكاتها.

يقدّم كل إصدار من حزمة تطوير برامج Android واجهات برمجة تطبيقات Java معيّنة يمكن لرمز المصدر الوصول إليها، كما يقدّم ميزة إزالة السكر لاستخدام واجهات برمجة التطبيقات هذه على إصدارات Android الأقدم.

JDK

حزمة تطوير Java التي تحتوي على مكتبات Java وملفات تنفيذية لتجميع رمز مصدر Java وتشغيل تطبيقات Java هناك العديد من حِزم JDK التي يتم استخدامها في إصدار Android. راجِع إصدارات Java في إصدارات Android للحصول على مزيد من التفاصيل.

نطاقات Gradle

يجمع Gradle العناصر الاعتمادية للمكتبات في نطاقات مختلفة (يُطلق عليها اسم الإعدادات في Gradle API)، ما يتيح لك تحديد مجموعات مختلفة من العناصر الاعتمادية للمكتبات لاستخدامها في أجزاء مختلفة من الإنشاء. على سبيل المثال، قد لا تريد تضمين مكتبات اختبار مثل JUnit في تطبيقك أو مكتبتك المنشورة، ولكنك تريد تضمينها عند إنشاء اختبارات الوحدة وتنفيذها. يمكنك أيضًا استخدام النطاقات لإضافة معالجات للرمز أو التعليقات التوضيحية لتحليل الرمز البرمجي.

على سبيل المثال، تحدِّد أداة AGP نطاقَي implementation وapi، وهما طريقتك في تحديد ما إذا كان يجب عرض أحد التبعيات لمستخدمي مشروعك الفرعي. اطّلِع على ضبط التبعيات للحصول على أوصاف لهذه النطاقات وغيرها من النطاقات المستخدَمة في إصدار Android.

أضِف تبعيات المكتبة في العنصر dependencies في ملفات الإنشاء، إما على شكل سلاسل group:artifact:version:

Kotlin

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation("com.example:library1:1.2.3")
    api("com.example:library2:1.1.1")
}

رائع

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation 'com.example:library1:1.2.3'
    api 'com.example:library2:1.1.1'
}

أو في كتالوج الإصدارات:

# Version catalog - gradle/libs.versions.toml
[versions]
exampleLib = "1.2.3"
examplePlugin = "2.3.4"

[libraries]
example-library = { group = "com.example", name = "library", version.ref = "exampleLib" }

[plugins]
example-plugin = { id = "com.example.plugin", version.ref = "examplePlugin" }

وحدِّد المتغيّرات التي تم إنشاؤها في ملفات الإنشاء:

Kotlin

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation(libs.example.library)
}

رائع

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation libs.example.library
}