نظرة عامة على إنشاء Gradle

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

ما هو التصميم؟

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

تضم المهام الأوامر التي تترجم مدخلاتها إلى والمخرجات. تحدِّد المكوّنات الإضافية المهام وتهيئتها. قيد التطبيق يقوم مكون إضافي في تصميمك بتسجيل مهامه، وربطها معًا باستخدام المدخلات والمخرجات.. على سبيل المثال، تطبيق المكوّن الإضافي لنظام Gradle المتوافق مع Android (AGP) إلى ملف الإصدار الخاص بك جميع المهام اللازمة لإنشاء APK، أو مكتبة Android. يتيح لك المكوّن الإضافي java-library إنشاء وعاء من مصدر Java الرمز. توجد مكوّنات إضافية مشابهة للغة Kotlin ولغات أخرى، لكن هناك مكونات إضافية أخرى تهدف إلى توسيع المكونات الإضافية. على سبيل المثال، يهدف المكوّن الإضافي protobuf إلى إضافة دعم Protobuf للمكونات الإضافية الحالية مثل AGP أو java-library.

يفضل Gradle الاصطلاح على التكوين بحيث تكون المكونات الإضافية مفيدة ثم إنشاء قيم افتراضية خارج المربع، ولكن يمكنك تهيئة الإصدار بشكل أكبر من خلال لغة خاصة بالنطاق (DSL) بيانية. تم تصميم DSL لذا يمكنك تحديد ما تريد إنشائه، بدلاً من كيفية إنشائه. المنطق في إلا أن المكونات الإضافية تدير "كيف". ويتم تحديد هذه الإعدادات عبر عدة أنظمة إنشاء الملفات في المشروع (والمشاريع الفرعية).

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

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

ماذا يحدث عند تشغيل إصدار Gradle؟

تعمل عمليات إنشاء Gradle على ثلاث مراحل. تنفذ كل مرحلة من هذه المراحل أجزاء مختلفة التي تحددها في ملفات التصميم.

  • تحدِّد الإعداد المشاريع والمشاريع الفرعية التي سيتم تضمينها. وإنشاء مسارات الفئات التي تحتوي على ملفات الإصدار المكونات الإضافية. تركز هذه المرحلة على ملف إعدادات تقوم فيه بالإعلان عن المشروعات والمواقع التي سيتم جلب المكوّنات الإضافية والمكتبات منها.
  • تسجِّل الإعدادات المهام لكلّ مشروع وتنفّذ عملية الإنشاء. لتطبيق مواصفات الإصدار الخاص بالمستخدم. من المهم أن تفهم أن رمز الضبط لن يكون بإمكانه الوصول إلى البيانات أو الملفات التي تم إنشاؤها أثناء التنفيذ.
  • يؤدي التنفيذ إلى تنفيذ "المبنى" الفعلي من تطبيقك. الناتج من التهيئة هو الرسم البياني الدائري الموجه (DAG) للمهام، التي تمثل جميع خطوات التصميم المطلوبة التي طلبها المستخدم (و المهام المقدمة في سطر الأوامر أو كإعدادات افتراضية في ملفات الإصدار). هذا النمط العلاقة بين المهام، سواء كانت صريحة في جدول مهام أو بناءً على مُدخلاته ومخرجاته. إذا كانت المهمة تحتوي على مدخلات هو ناتج مهمة أخرى، فينبغي تشغيله بعد المهمة الأخرى. هذا النمط تنفيذ المهام القديمة بالترتيب المحدد في الرسم البياني؛ إذا كانت المهمة حيث لم يطرأ أي تغيير على المدخلات منذ آخر مرة تنفيذها، فستتخطىها Gradle.

لمزيد من المعلومات، اطّلِع على مراحل إنشاء Gradle.

إعداد DSL

يستخدم Gradle لغة خاصة بالنطاق (DSL) لإعداد الإصدارات. يركز هذا النهج التعريفي على تحديد بياناتك بدلاً من وكتابة التعليمات خطوة بخطوة (الضرورية).

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

على سبيل المثال، قد يبدو ضبط جزء Android من إصدارك على النحو التالي:

Kotlin

android {
    namespace = "com.example.app"
    compileSdk = 34
    // ...

    defaultConfig {
        applicationId = "com.example.app"
        minSdk = 34
        // ...
    }
}

Groovy

android {
    namespace 'com.example.myapplication'
    compileSdk 34
    // ...

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdk 24
        // ...
    }
}

وراء الكواليس، يشبه رمز DSL ما يلي:

fun Project.android(configure: ApplicationExtension.() -> Unit) {
    ...
}

interface ApplicationExtension {
    var compileSdk: Int
    var namespace: String?

    val defaultConfig: DefaultConfig

    fun defaultConfig(configure: DefaultConfig.() -> Unit) {
        ...
    }
}

يتم تمثيل كل كتلة في DSL بدالة تأخذ lambda إلى وتهيئته، وخاصية بالاسم نفسه للوصول إليها. هذا يجعل التعليمات البرمجية في ملفات الإصدار الخاصة بك أشبه بمواصفات البيانات.

التبعيات الخارجية

قدَّم نظام تصميم Maven مواصفات التبعية، نظام التخزين والإدارة. يتم تخزين المكتبات في المستودعات (الخوادم أو الدلائل)، مع البيانات الوصفية التي تشمل إصداراتها وتبعياتها على المكتبات الأخرى. تقوم بتحديد والمستودعات التي يتم البحث فيها وإصدارات التبعيات التي تريد استخدامها وإنشاء تنزيلات النظام لها أثناء عملية الإنشاء.

يتم تحديد عناصر Maven حسب اسم المجموعة (الشركة أو المطوّر أو غير ذلك) أو العناصر. اسم (اسم المكتبة) وإصدار هذا العنصر. عادةً ما تكون هذه يتم تمثيلها باسم group:artifact:version.

يساهم هذا النهج في تحسين إدارة الإصدارات بشكل كبير. ستسمع غالبًا مثل تسمى "مستودعات Maven"، ولكن الأمر كله يتعلق بالطريقة التي يتم حزمها ونشرها. كانت هذه المستودعات وبيانات التعريف إعادة استخدامها في العديد من أنظمة التصميم، بما في ذلك Gradle (ويمكنها النشر في هذه المستودعات). تسمح المستودعات العامة بالمشاركة للجميع تحتفظ مستودعات الشركة بالتبعيات الداخلية داخل الشركة.

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

سنخوض في مزيد من التفاصيل حول كيفية تحديد التبعيات في إضافة إصدار. والتبعيات لديك.

إنشاء الصيغ

عند إنشاء تطبيق Android، ستحتاج عادةً إلى إنشاء عدة تطبيقات المتغيرات. تحتوي الصِيَغ على رموز مختلفة أو تم إنشاؤها باستخدام خيارات المنتج، وتتألف من أنواع التصميم ونكهات المنتجات.

تختلف أنواع الإصدارات من خيارات الإصدار المعلَن عنها. بشكل افتراضي، يقوم AGP بإعداد "release" و "تصحيح الأخطاء" ولكن يمكنك تعديلها وإضافة المزيد (ربما مرحلي أو اختبار داخلي).

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

يعمل إصدار الإصدار على تحسين التطبيق وتوقيعه باستخدام مفتاح الإصدار يحمي ملفات التطبيقات المثبتة.

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

تنشئ AGP متغيرات لكل مزيج من نوع التصميم ونكهة المنتج. في حال حذف لا تحدد النكهات، يتم تسمية المتغيرات باسم أنواع الإنشاء. إذا كنت نحدد كليهما، يكون اسم الصيغة <flavor><Buildtype>. على سبيل المثال، باستخدام الإصدار النوعين release وdebug، والنكهات demo وfull، فإن AGP سينشئ خيارات المنتج:

  • demoRelease
  • demoDebug
  • fullRelease
  • fullDebug

الخطوات التالية

الآن بعد أن اطّلعت على مفاهيم الإصدار، ألقِ نظرة على إصدار Android الهيكلية في مشروعك.