تخصيص الموارد التي تريد الاحتفاظ بها

عند تفعيل ميزة تحسين التطبيقات، يوجّه الإعداد isShrinkResources = true أداة التحسين إلى إزالة الموارد غير المستخدَمة، ما يساعد في تقليل حجم تطبيقك. لا تعمل ميزة تقليل حجم الموارد إلا مع ميزة تقليل حجم الرموز، لذا إذا كنت بصدد تحسين الموارد، اضبط أيضًا isMinifyEnabled = true، على سبيل المثال:

buildTypes {
    release {
        isMinifyEnabled = true
        isShrinkResources = true
        ...
    }
}

إذا كنت تريد الاحتفاظ بموارد معيّنة أو تجاهلها، أنشئ ملف XML للاحتفاظ بالموارد في موارد مشروعك، على سبيل المثال res/raw/my.package.keep.xml. يتضمّن ملف keepملف المكوّنات التالية:

  • علامة <resources>: تحتوي على جميع عناصر الموارد الفرعية وسمات الاحتفاظ/الاستبعاد.
  • سمة tools:keep: تقبل قائمة مفصولة بفواصل بأسماء موارد تحدد الموارد التي يجب الاحتفاظ بها
  • سمة tools:discard: تقبل قائمة مفصولة بفواصل بأسماء موارد تحدد الموارد المطلوب تجاهلها

استخدِم علامة النجمة كحرف بدل للإشارة إلى موارد متعدّدة في المجلد نفسه، على سبيل المثال:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
    tools:discard="@layout/unused2" />

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

استهداف أنواع إصدارات معيّنة

لإزالة الموارد في بعض صيغ الإصدار فقط، ضَع جميع مواردك في دليل المشروع المشترك، ثم أنشئ ملفًا مختلفًا my.package.build.variant.keep.xml لكل صيغة إصدار في دليل موارد الصيغة. في ملف keep، حدِّد يدويًا الموارد التي تريد إزالتها عندما يبدو أنّه يتم استخدام موارد معيّنة في الرمز البرمجي (وبالتالي لن تتم إزالتها من خلال أداة تقليل حجم الملفات)، ولكنك تعلم أنّه لن يتم استخدامها في الصيغة المحدّدة للإصدار.

إزالة الموارد البديلة غير المستخدَمة

لا يزيل المحسِّن سوى الموارد التي لا يشير إليها رمز تطبيقك، ما يعني أنّه لن يزيل الموارد البديلة لإعدادات الأجهزة المختلفة.

استخدِم سمة resConfigs في أداة Android Gradle في ملف build.gradle وحدة تطبيقك لإزالة ملفات الموارد البديلة التي لا يحتاج إليها تطبيقك.

على سبيل المثال، إذا كنت تستخدم مكتبة تتضمّن موارد لغوية (مثل خدمات Google Play)، سيتضمّن تطبيقك جميع سلاسل اللغات المترجَمة للرسائل الواردة في هذه المكتبات، سواءً كانت بقية أجزاء تطبيقك مترجمة إلى اللغات نفسها أم لا. للاحتفاظ فقط باللغات التي يقبلها تطبيقك رسميًا، حدِّد هذه اللغات باستخدام السمة resConfigs. تتم إزالة أيّ موارد للّغات غير المحدّدة.

توضِّح المقتطفات التالية كيفية حصر موارد اللغة باللغة الإنجليزية والفرنسية فقط:

android {
    defaultConfig {
        ...
        resourceConfigurations.addAll(listOf("en", "fr"))
    }
}

أو

android {
    defaultConfig {
        ...
        resConfigs "en", "fr"
    }
}

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

بالنسبة إلى التطبيقات القديمة التي يتم إصدارها باستخدام حِزم APK (التي تم إنشاؤها قبل آب/أغسطس 2021)، يمكنك تخصيص كثافة الشاشة أو موارد ABI لتضمينها في حزمة APK من خلال إنشاء حِزم APK متعددة تستهدف إعدادات أجهزة مختلفة.

تجنُّب التعارضات عند دمج الموارد

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

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

تبحث ميزة "التحسين من خلال الربط" عن الموارد المكرّرة في المواضع التالية:

  • المراجع الرئيسية المرتبطة بمجموعة المصادر الرئيسية، والتي يمكن العثور عليها بشكل عام في src/main/res/
  • تراكب الأسعار المتغيرة، من نوع الإصدار ونكهاته
  • العناصر التابعة لمشروع المكتبة

تدمج AGP الموارد المكرّرة بالترتيب التدرّجي التالي للأولوية:

التبعيات → الخيار الرئيسي → نوع النكهة → نوع التصميم

على سبيل المثال، إذا ظهر مورد مكرّر في كلّ من مواردك الرئيسية وأحد ملفّات ملفّات طعم الإصدار، سيختار Gradle المورد في ملف طعم الإصدار.

إذا ظهرت موارد متطابقة في مجموعة المصادر نفسها، لا يمكن لحلّ Gradle دمجها ويُصدر خطأ في دمج الموارد. يمكن أن يحدث ذلك إذا حدّدت عدة مجموعات مصدر في سمة sourceSet لملف الوحدة build.gradle، على سبيل المثال، إذا كان كل من src/main/res/ وsrc/main/res2/ يحتويان على موارد متطابقة.

تحديد المشاكل وحلّها في ما يتعلّق بتقليص الموارد

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

:android:shrinkDebugResources
Removed unused resources: Resource data reduced from 2570KB to 1711KB: Removed 33%
:android:validateDebugSigning

ينشئ Gradle أيضًا ملف بيانات تشخيص باسم resources.txt في <module-name>/build/outputs/mapping/release/ (المجلد نفسه الذي يحتوي علىملفّات ناتج ProGuard). يتضمّن الملف تفاصيل مثل الموارد التي تشير إلى موارد أخرى والموارد المستخدَمة أو التي تمّت إزالتها.

على سبيل المثال، لمعرفة سبب استمرار ظهور @drawable/ic_plus_anim_016 في تطبيقك، افتح ملف resources.txt وابحث عن اسم الملف هذا. قد تلاحظ أنّه تمت الإشارة إليه من مرجع آخر:

16:25:48.005 [QUIET] [system.out] @drawable/add_schedule_fab_icon_anim : reachable=true
16:25:48.009 [QUIET] [system.out] @drawable/ic_plus_anim_016

عليك الآن معرفة سبب إمكانية الوصول إلى @drawable/add_schedule_fab_icon_anim. وإذا بحثت للأعلى، ستجد المرجع مُدرَجًا ضمن العنوان الموارد الجذر التي يمكن الوصول إليها هي: في resources.txt.

وهذا يعني أنّ هناك رمزًا يشير إلى add_schedule_fab_icon_anim، أي أنّه تم العثور على معرّف R.drawable في الرمز الذي يمكن الوصول إليه.

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

10:32:50.590 [QUIET] [system.out] Marking drawable:ic_plus_anim_016:2130837506
    used because its format-string matches string pool constant ic_plus_anim_%1$d.

إذا ظهرت لك إحدى هذه السلاسل وكنت متأكدًا من عدم استخدام السلسلة لتحميل المورد المحدّد ديناميكيًا، استخدِم سمة tools:discard في ملف keep لإعلام نظام الإنشاء بإزالة المورد.