إنشاء ملف شخصي

قد تتطلب منك المشاريع الأكبر، أو تلك التي تنفّذ الكثير من منطق الإنشاء المخصص، إلقاء نظرة أعمق في عملية الإنشاء للعثور على المعوقات. يمكنك القيام بذلك عن طريق تحديد ملامح المدة التي تستغرقها Gradle لتنفيذ كل مرحلة من مراحل دورة حياة الإنشاء ومهمة الإنشاء. على سبيل المثال، إذا أظهر الملف الشخصي للإصدار أنّ Gradle يقضي وقتًا طويلاً في ضبط مشروعك، قد يقترح عليك نقل منطق الإصدار المخصص من مرحلة الإعداد. بالإضافة إلى ذلك، إذا كانت مهمة mergeDevDebugResources يستهلك قدرًا كبيرًا من وقت الإنشاء، قد يشير ذلك إلى أنّك بحاجة إلى تحويل صورك إلى تنسيق WebP أو إيقاف تعديل الصور بتنسيق PNG.

إذا كنت تستخدم الإصدار Android Studio 4.0 أو إصدارًا أحدث، إنّ أفضل طريقة للتحقّق من مشاكل أداء الإصدار هي استخدام أداة تحليل الإصدارات.

بالإضافة إلى ذلك، يتوفّر لك خياران من أجل تحديد ملامح تصميمك خارج "استوديو Android":

  1. أداة gradle-profiler المستقلة، وهي أداة فعّالة لإجراء تحليل دقيق لإصدارك.

  2. استخدِم Gradle --profile، وهو أداة سهلة الاستخدام متاحة في سطر أوامر Gradle.

استخدام أداة gradle-profiler المستقلة

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

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

تتضمن بعض تكوينات إعداد المشروع لقياس الأداء ما يلي:

  • إصدارات المكونات الإضافية
  • إصدارات Gradle
  • إعدادات JVM (حجم الذاكرة والحجم الدائم ومجموعة البيانات غير الصالحة وغير ذلك)
  • عدد عمال Gradle (org.gradle.workers.max)
  • خيارات لكل مكوّن إضافي لتحسين الأداء بشكل أكبر

البدء

  • عليك تثبيت grale-profiler باتّباع هذه التعليمات.
  • عملية التنفيذ: gradle-profiler --benchmark --project-dir <root-project> :app:assembleDebug

سيكون هذا قياس أداء إصدار محدّث بالكامل لأنّ "--benchmark" يدير المهمة عدة مرات بدون تغيير المشروع فيما بينهما. بعد ذلك، سينشئ تقرير HTML ضمن دليل profile-out/ يعرض لك أوقات الإنشاء.

هناك سيناريوهات أخرى قد تكون أكثر فائدة لقياس الأداء:

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

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

تحديد إعدادات مختلفة للذاكرة/وحدة المعالجة المركزية (CPU)

لقياس إعدادات الذاكرة ووحدة المعالجة المركزية المختلفة، يمكنك إنشاء سيناريوهات متعددة تستخدم قيمًا مختلفة لـ org.gradle.jvmargs. على سبيل المثال، يمكنك إنشاء سيناريوهات:

# <root-project>/scenarios.txt
clean_build_2gb_4workers {
    tasks = [":app:assembleDebug"]
    gradle-args = ["--max-workers=4"]
    jvm-args = ["-Xmx2048m"]
    cleanup-tasks = ["clean"]
}
clean_build_parallelGC {
    tasks = [":app:assembleDebug"]
    jvm-args = ["-XX:+UseParallelGC"]
    cleanup-tasks = ["clean"]
}

clean_build_G1GC_4gb {
    tasks = [":app:assembleDebug"]
    jvm-args = ["-Xmx4096m", "-XX:+UseG1GC"]
    cleanup-tasks = ["clean"]
}

من خلال تشغيل gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt، سيتم تنفيذ ثلاثة سيناريوهات، وستتمكّن من مقارنة المدة التي يستغرقها :app:assembleDebug لكل إعداد من هذه الإعدادات.

إنشاء ملفات تعريفية لإصدارات مختلفة من مكوّنات Gradle الإضافية

لمعرفة كيف يؤثر تغيير إصدار مكون Gradle الإضافي على أوقات الإنشاء، قم بإنشاء سيناريو لقياس ذلك. يتطلب هذا بعض التحضير لجعل إصدار المكون الإضافي قابلاً للتطبيق من السيناريو. غيَّر الإصدار الأساسي من بنية الجذر:

# <root-project>/build.gradle
buildscript {
    def agpVersion = providers.systemProperty("agpVersion").forUseAtConfigurationTime().orNull ?: '4.1.0'

    ext.kotlin = providers.systemProperty('kotlinVersion').forUseAtConfigurationTime().orNull ?: '1.4.0'

    dependencies {
        classpath "com.android.tools.build:gradle:$agpVersion"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin"
    }
}

يمكنك الآن تحديد المكوّن الإضافي لنظام Gradle المتوافق مع Android وإصدارات مكوّنات Kotlin Gradle من ملف السيناريوهات، وجعل السيناريو يضيف طريقة جديدة إلى الملفات المصدر:

# <root-project>/scenarios.txt
non_abi_change_agp4.1.0_kotlin1.4.10 {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    System-properties {
      "agpVersion" = "4.1.0"
      "kotlinVersion" = "1.4.10"
}

non_abi_change_agp4.2.0_kotlin1.4.20 {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    System-properties {
      "agpVersion" = "4.2.0-alpha16"
      "kotlinVersion" = "1.4.20"
}

إنشاء ملفات تعريفية لإصدار تزايدي

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

# <root-project>/scenarios.txt
non_abi_change {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to = ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
}

abi_change {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to = ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
}

layout_change {
    tasks = [":app:assembleDebug"]
    apply-android-layout-change-to = "app/src/main/res/your_layout_file.xml"
}
string_resource_change {
    tasks = [":app:assembleDebug"]
    apply-android-resource-value-change-to = "app/src/main/res/values/strings.xml"
}

وسيؤدي تشغيل gradle-profiler --benchmark --project-dir &lt;root-project> --scenario-file scenarios.txt إلى إنشاء تقرير HTML الذي يتضمّن بيانات قياس الأداء.

يمكنك دمج السيناريوهات التزايدية مع إعدادات أخرى، مثل حجم الذاكرة أو عدد العاملين أو إصدار Gradle:

# <root-project>/scenarios.txt
non_abi_change_4g {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx4096m"]
}

non_abi_change_4g_8workers {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx4096m"]
    gradle-args = ["--max-workers=8"]
}

non_abi_change_3g_gradle67 {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx3072m"]
    version = ["6.7"]
}

تحديد ملامح إصدار نظيف

من أجل قياس أداء تصميم نظيف، يمكنك إنشاء سيناريو سيتم استخدامه لدفع تنفيذ ملف التعريف:

# <root-project>/scenarios.txt
clean_build {
    tasks = [":app:assembleDebug"]
    cleanup-tasks = ["clean"]
}

ولتشغيل هذا السيناريو، استخدم الأمر التالي:

gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt

استخدام خيار Gradle --profile

لإنشاء ملف شخصي للإصدار وعرضه من خلال سطر أوامر Gradle، عليك اتّباع الخطوات التالية:

  1. افتح وحدة طرفية لسطر الأوامر في جذر مشروعك.
  2. نفِّذ إصدار نظيف من خلال إدخال الأمر التالي. أثناء تحليل إصدارك، عليك إنشاء إصدار نظيف بين كل إصدار وملفك الشخصي لأنّ Gradle يتخطّى المهام عند عدم تغيير الإدخال إلى مهمة (مثل رمز المصدر). وبالتالي، يعمل الإصدار الثاني الذي لا يتضمّن تغييرات في الإدخالات دائمًا بشكل أسرع بسبب عدم إعادة تشغيل المهام. وبالتالي، فإن تنفيذ مهمة clean بين الإصدارات يضمن لك تحليل عملية الإصدار بالكامل.
    // On Mac or Linux, run the Gradle wrapper using "./gradlew".
    gradlew clean
    
  3. نفِّذ إنشاء تصحيح أخطاء لإحدى نكهات منتجاتك، مثل صيغة "dev"، باستخدام العلامات التالية:
    gradlew --profile --offline --rerun-tasks assembleFlavorDebug
    
    • --profile: تفعيل إنشاء الملفات التعريفية
    • --offline: إيقاف Gradle من جلب الاعتماديات على الإنترنت. بهذه الطريقة، نحرص على ألا تتداخل أي تأخيرات ناتجة عن محاولة Gradle لتعديل تبعياتك مع بيانات التحليل. من المفترض أن تكون قد أنشأت مشروعك مرة واحدة للتأكّد من أنّ Gradle قد نزّلت تبعياتك وتخزينها مؤقتًا.
    • --rerun-tasks: يفرض على Gradle إعادة تنفيذ جميع المهام وتجاهل أي عمليات تحسين للمهام.
  4. الشكل 1. عرض مشروع يشير إلى موقع تقارير الملفات الشخصية

    بعد اكتمال التصميم، استخدِم نافذة المشروع وانتقِل إلى دليل project-root/build/reports/profile/ (كما هو موضّح في الشكل 1).

  5. انقر بزر الماوس الأيمن على ملف profile-timestamp.html واختَر فتح في المتصفح > تلقائي. من المفترَض أن يبدو التقرير مشابهًا للتقرير المعروض في الشكل 2. يمكنك فحص كل علامة تبويب في التقرير لمعرفة المزيد عن الإصدار الذي تستخدمه، مثل علامة التبويب تنفيذ المهام التي تعرض المدة التي استغرقتها Gradle في تنفيذ كل مهمة إصدار.

    الشكل 2. عرض تقرير في متصفّح.

  6. اختياري: قبل إجراء أي تغييرات على مشروعك أو إعدادات الإصدار، كرِّر الأمر في الخطوة 3 مع حذف العلامة --rerun-tasks. بما أنّ أداة Gradle تحاول توفير الوقت عن طريق عدم إعادة تنفيذ المهام التي لم يتم تغيير مدخلاتها (يُشار إليها باسم UP-TO-DATE في علامة التبويب تنفيذ المهام من التقرير، كما هو موضّح في الشكل 3)، يمكنك تحديد المهام التي تؤدي مهامًا في الحالات غير المناسبة. على سبيل المثال، إذا لم يتم وضع علامة UP-TO-DATE على :app:processDevUniversalDebugManifest، قد يشير ذلك إلى أنّ إعدادات الإصدار تُجري تعديلاً ديناميكيًا على البيان مع كل إصدار. ومع ذلك، يجب تشغيل بعض المهام أثناء كل إصدار، مثل :app:checkDevDebugManifest.

    الشكل 3. عرض نتائج تنفيذ المهام

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

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

الشكل 4. يمكنك عرض تقرير جديد بعد تحسين سرعة الإصدار.