ولجعل تطبيقك صغيرًا وسريعًا قدر الإمكان، يجب إجراء تحسينات وتصغير
إصدار تطبيقك باستخدام isMinifyEnabled = true
.
ويؤدي ذلك إلى تفعيل التصغير، ما يؤدي إلى إزالة الرموز والموارد غير المستخدَمة. إخفاء مفاتيح فك التشفير، الذي يختصر أسماء فئات تطبيقك وأعضائه أو التحسين، الذي يطبّق استراتيجيات أكثر صرامة لتقليل الحجم وتحسين أداء التطبيق. تصف هذه الصفحة كيف تصف R8 وتنفيذ مهام وقت التجميع هذه لمشروعك وكيف يمكنك تخصيص معهم.
عندما تنشئ مشروعك باستخدام الإصدار 3.4.0 من المكوّن الإضافي لنظام Gradle المتوافق مع Android أو الإصدارات الأحدث لم يعد المكون الإضافي يستخدم ProGuard لتحسين رمز وقت التجميع. بدلاً من ذلك، يعمل المكوّن الإضافي مع المحول البرمجي لـ R8 للتعامل مع ما يلي مهام وقت التجميع:
- تقليص الرموز (أو اهتزاز الشجرة): يتم رصد الرموز غير المستخدَمة وإزالتها بأمان. الفئات والحقول والطرق والسمات من تطبيقك ومكتبته والتبعيات لديك (مما يجعلها أداة قيمة للعمل حول الحدّ الأقصى المرجعي 64 ألف). على سبيل المثال، إذا كنت تستخدم عدد قليل فقط من واجهات برمجة التطبيقات التابعة لتبعية مكتبة، ويمكن أن يؤدي تقليص العمل إلى تحديد رمز المكتبة أنّ تطبيقك لا يستخدم ذلك الرمز فقط ويزيله من التطبيق إلى لمعرفة المزيد، يُرجى الانتقال إلى القسم الخاص بكيفية تقليص الرمز.
- تقلّص الموارد: لإزالة الموارد غير المستخدَمة من تطبيقك المجمّع، بما في ذلك الموارد غير المستخدَمة ضمن ملحقات مكتبة تطبيقك تعمل في مع تقليص الرمز، إذ يتم حذف الأكواد غير المستخدمة يمكن أيضًا إزالة أي موارد لم تعد مُشار إليها بأمان. للتعلّم انتقل إلى القسم الذي يتناول كيفية تقليص مواردك.
- التحسين: يفحص الرمز البرمجي ويعيد كتابته لتحسين وقت التشغيل
الأداء وتقليل حجم ملفات DEX في تطبيقك هذا النمط
تحسين أداء وقت تشغيل الرمز البرمجي بنسبة تصل إلى 30%، ما يؤدي إلى تحسين أداء الرمز البرمجي بدرجة كبيرة
توقيت بدء التشغيل والإطار. على سبيل المثال، إذا رصدت R8 أنّ
else {}
فرع لجملة if/else معينة، تزيل R8 التعليمة البرمجية فرعelse {}
. لمزيد من المعلومات، انتقِل إلى القسم حول تحسين الرموز. - الإخفاء (أو تصغير المعرّف): اختصار اسم الفئات وأعضاء الفريق، ما يؤدي إلى تقليل أحجام ملفات DEX. لمزيد من المعلومات، يُرجى الانتقال إلى القسم الذي يتناول كيفية إخفاء مفاتيح فك التشفير.
عند إنشاء إصدار إصدار تطبيقك، يمكن ضبط R8 لتنفيذ مهام وقت التجميع الموضحة أعلاه من أجلك. يمكنك أيضًا إيقاف بعض أو تخصيص سلوك R8 من خلال ملفات قواعد ProGuard. في الواقع، تعمل R8 مع جميع ملفات قواعد ProGuard الحالية، لذلك إنّ تحديث المكوّن الإضافي لنظام Gradle المتوافق مع Android لاستخدام R8 لن يتطلّب منك تغيير قواعدك الحالية.
تفعيل التقليل والتشويش والتحسين
عند استخدام الإصدار 3.4.0 من المكوّن الإضافي لنظام Gradle المتوافق مع Android أو الإصدار 3.4.0 والإصدارات الأحدث من "استوديو Android"، يكون R8 هو المحول البرمجي الافتراضي الذي يحول كود بايت Java لمشروعك إلى DEX يعمل على نظام Android الأساسي. ومع ذلك، عند إنشاء مشروع جديد باستخدام Android Studio، ولا يتم إجراء تضييق نطاق وإخفاء مفاتيح فك التشفير وتحسين الرموز البرمجية مُفعَّلة تلقائيًا. وهذا لأن تحسينات وقت التجميع هذه تزيد من وقت إنشاء مشروعك وقد تقدم أخطاء إذا لم تكن تخصيص الرمز الذي تريد الاحتفاظ به
لذلك، من الأفضل تمكين مهام وقت التجميع هذه عند إنشاء الإصدار النهائي في تطبيقك تختبره قبل نشره لتمكين تقليص أو تشويش والتحسين، قم بتضمين ما يلي في النص البرمجي للإصدار على مستوى المشروع.
Kotlin
android { buildTypes { getByName("release") { // Enables code shrinking, obfuscation, and optimization for only // your project's release build type. Make sure to use a build // variant with `isDebuggable=false`. isMinifyEnabled = true // Enables resource shrinking, which is performed by the // Android Gradle plugin. isShrinkResources = true proguardFiles( // Includes the default ProGuard rules files that are packaged with // the Android Gradle plugin. To learn more, go to the section about // R8 configuration files. getDefaultProguardFile("proguard-android-optimize.txt"), // Includes a local, custom Proguard rules file "proguard-rules.pro" ) } } ... }
Groovy
android { buildTypes { release { // Enables code shrinking, obfuscation, and optimization for only // your project's release build type. Make sure to use a build // variant with `debuggable false`. minifyEnabled true // Enables resource shrinking, which is performed by the // Android Gradle plugin. shrinkResources true // Includes the default ProGuard rules files that are packaged with // the Android Gradle plugin. To learn more, go to the section about // R8 configuration files. proguardFiles getDefaultProguardFile( 'proguard-android-optimize.txt'), 'proguard-rules.pro' } } ... }
ملفات إعداد R8
يستخدم R8 ملفات قواعد ProGuard لتعديل السلوك التلقائي وتحسين فهم بنية تطبيقك، مثل الفئات التي تعمل كنقاط دخول في رمز التطبيق. على الرغم من أنّه يمكنك تعديل بعض ملفات القواعد هذه، قد يتم إنشاء قواعد تلقائيًا باستخدام أدوات وقت التجميع مثل AAPT2 أو مُكتسَبة من ملحقات مكتبة التطبيق. يصف الجدول التالي مصادر ملفات قواعد ProGuard التي تستخدمها R8.
المصدر | الموقع الجغرافي | الوصف |
استوديو Android | <module-dir>/proguard-rules.pro
|
عند إنشاء وحدة جديدة باستخدام "استوديو Android"، تنشئ بيئة التطوير المتكاملة (IDE)
proguard-rules.pro في الدليل الجذر لتلك الوحدة.
لا يطبّق هذا الملف أي قواعد تلقائيًا. لذلك، قم بتضمين خياراتك قواعد ProGuard هنا، مثل مخصّص الاحتفاظ بالقواعد. |
المكوّن الإضافي لنظام Gradle المتوافق مع Android | يتم إنشاؤه باستخدام المكوّن الإضافي لنظام Gradle المتوافق مع Android في وقت التجميع. | ينشئ المكوّن الإضافي لنظام Gradle المتوافق مع Android
proguard-android-optimize.txt ، بما في ذلك القواعد
مفيدة لمعظم مشروعات Android
@Keep*
التعليقات التوضيحية.
بشكل افتراضي، عند إنشاء وحدة جديدة باستخدام استوديو Android، يمكن تعيين يتضمن نص الإصدار ملف القواعد هذا في إصدار الإصدار لك.
ملاحظة: يتضمّن المكوّن الإضافي لنظام Gradle المتوافق مع Android حزمة ProGuard إضافية محدّدة مسبقًا
ولكن يوصى باستخدام
|
تبعيات المكتبة |
في مكتبة AAR:
في مكتبة JAR: بالإضافة إلى هذه المواقع، يتوفّر الإصدار 3.6 من المكوّن الإضافي لنظام Gradle المتوافق مع Android أو الإصدارات الأحدث يتوافق مع قواعد الانكماش المستهدفة. |
في حال نشر مكتبة ملفات AAR أو JAR مع ملف القواعد الخاص بها، يجب تقوم بتضمين هذه المكتبة كتبعية لوقت التجميع، فإن R8 تلقائيًا ويطبق هذه القواعد عند تجميع مشروعك. بالإضافة إلى قواعد ProGuard التقليدية، المكوّن الإضافي لنظام Gradle المتوافق مع Android الإصدار 3.6 أو الإصدارات الأحدث يدعم أيضًا قواعد الانكماش المستهدفة. هذه هي القواعد تستهدف أدوات تخفيض حجم معيّنة (R8 أو ProGuard)، بالإضافة إلى منتجات محددة الإصدارات الأكثر تخفيضًا. يكون استخدام ملفات القواعد المجمعة مع المكتبات مفيدًا في حالة هناك قواعد مطلوبة حتى تعمل المكتبة بشكل صحيح - أي مكتبة نفذ مطوّر البرامج خطوات تحديد المشاكل وحلّها نيابةً عنك. مع ذلك، يجب أن تدرك أنّ هذه القواعد مضافة، كما أنّ هذه القواعد لا يمكن إزالة بعض القواعد التي تتضمنها تبعية المكتبة في تجميع أجزاء أخرى من تطبيقك. على سبيل المثال، إذا كانت قاعدة لإيقاف تحسينات الرمز البرمجي، وتعمل هذه القاعدة على إيقاف التحسينات لمشروعك بأكمله. |
أداة حزمة مواد العرض في Android 2 (AAPT2) | بعد إنشاء مشروعك باستخدام minifyEnabled true :
<module-dir>/build/intermediates/aapt_proguard_file/.../aapt_rules.txt
|
ينشئ AAPT2 القواعد استنادًا إلى الإشارات إلى الفئات في تطبيقك والبيان والتخطيطات وموارد التطبيق الأخرى. على سبيل المثال، تتضمن AAPT2 العنصر لكل نشاط تسجله في بيان تطبيقك نقطة دخول متعددة. |
ملفات الإعداد المخصّصة | بشكل تلقائي، عند إنشاء وحدة جديدة باستخدام "استوديو Android"، يتعاون بيئة التطوير المتكاملة (IDE)
تنشئ <module-dir>/proguard-rules.pro لك لإضافة نصّك الخاص.
القواعد.
|
ويمكنك تضمين عمليات ضبط إضافية. وتطبقها R8 في وقت التجميع. |
عند ضبط السمة minifyEnabled
على true
، تجمع R8 القواعد من الكل
المصادر المتاحة المدرجة أعلاه. من المهم تذكر ذلك عند
يمكنك تحديد المشاكل وحلّها باستخدام R8، لأنّ التبعيات الأخرى في وقت التجميع،
مثل تبعيات المكتبة إلى حدوث تغييرات في سلوك R8 الذي
لا تعرفها عنه.
لإخراج تقرير كامل بجميع القواعد التي تنطبق عليها R8 عند إنشاء
عليك تضمين ما يلي في ملف proguard-rules.pro
للوحدة:
// You can specify any path and filename.
-printconfiguration ~/tmp/full-r8-config.txt
قواعد الانكماش المستهدفة
الإصدار 3.6 من المكوّن الإضافي لنظام Gradle المتوافق مع Android أو الإصدارات الأحدث يدعم المكتبات القواعد التي تستهدف أجهزة تصغير محددة (R8 أو ProGuard)، بالإضافة إلى إصدارات معينة لتقليص العرض. هذا النمط تسمح لمطوّري المكتبات بتخصيص قواعدهم للعمل بشكل مثالي في المشروعات التي تستخدم إصدارات جديدة تقلص البيانات، مع السماح بمتابعة القواعد الحالية المستخدم في المشروعات ذات الإصدارات القديمة المخفضة.
لتحديد قواعد الانكماش المستهدَف، على مطوّري المكتبات تضمينها. في مواقع جغرافية محدّدة داخل مكتبة AAR أو JAR، كما هو موضّح أدناه
In an AAR library:
proguard.txt (legacy location)
classes.jar
└── META-INF
└── com.android.tools (targeted shrink rules location)
├── r8-from-<X>-upto-<Y>/<R8-rules-file>
└── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>
In a JAR library:
META-INF
├── proguard/<ProGuard-rules-file> (legacy location)
└── com.android.tools (targeted shrink rules location)
├── r8-from-<X>-upto-<Y>/<R8-rules-file>
└── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>
وهذا يعني أنّه يتم تخزين قواعد الانكماش المستهدَف في META-INF/com.android.tools
.
دليل JAR أو في دليل META-INF/com.android.tools
داخل
classes.jar
من AAR.
ضمن هذا الدليل، يمكن أن تكون هناك عدة أدلة تحمل أسماء في النموذج
r8-from-<X>-upto-<Y>
أو proguard-from-<X>-upto-<Y>
للإشارة إلى أي
والتي تقلل من القواعد الموجودة داخل الأدلة.
يُرجى العلم أنّ الجزأين -from-<X>
و-upto-<Y>
اختياريان، وهما إصدار <Y>
.
حصريًا، ويجب أن تكون نطاقات الإصدارات مستمرة.
على سبيل المثال، r8-upto-8.0.0
وr8-from-8.0.0-upto-8.2.0
وr8-from-8.2.0
تشكل مجموعة صالحة من قواعد الانكماش المستهدفة. تعمل القواعد بموجب
سيتم استخدام الدليل r8-from-8.0.0-upto-8.2.0
بواسطة R8 من الإصدار 8.0.0 إلى
ولكن لا يتم تضمين الإصدار 8.2.0.
وبناءً على هذه المعلومات، سيحدِّد المكوّن الإضافي لنظام Gradle المتوافق مع Android 3.6 أو الإصدارات الأحدث
من أدلة R8 المطابقة. إذا لم تحدّد المكتبة الاستهدافات
سيحدد المكوّن الإضافي لنظام Gradle المتوافق مع Android القواعد من
المواقع الجغرافية (proguard.txt
الخاصة بالاقتراحات المطبّقة تلقائيًا أو
META-INF/proguard/<ProGuard-rules-file>
مقابل JAR).
يمكن لمطوّري المكتبات اختيار تضمين إما قواعد الانكماش المستهدفة أو القديمة قواعد ProGuard في مكتباتها أو كلا النوعين إذا كانوا يريدون الاحتفاظ التوافق مع المكوّن الإضافي لنظام Gradle المتوافق مع Android الأقدم من 3.6 أو الأدوات الأخرى
تضمين إعدادات إضافية
عند إنشاء مشروع أو وحدة جديدة باستخدام "استوديو Android"، تنشئ بيئة التطوير المتكاملة (IDE)
<module-dir>/proguard-rules.pro
لك لتضمين قواعدك الخاصة. إِنْتَ
أن تتضمّن أيضًا قواعد إضافية من ملفات أخرى من خلال إضافتها إلى
السمة proguardFiles
في النص البرمجي لإنشاء الوحدة.
على سبيل المثال، يمكنك إضافة قواعد خاصة بكل صيغة إصدار من خلال إضافة
سمة proguardFiles
أخرى في مجموعة productFlavor
المقابلة تشير رسالة الأشكال البيانية
يضيف ملف Gradle التالي flavor2-rules.pro
إلى نكهة المنتج flavor2
.
والآن، يستخدم flavor2
جميع قواعد ProGuard الثلاث، لأن تلك القواعد من release
كتلة العناوين أيضًا.
بالإضافة إلى ذلك، يمكنك إضافة السمة testProguardFiles
التي تحدّد
قائمة بملفات ProGuard المضمّنة في حِزمة APK التجريبية فقط:
Kotlin
android { ... buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), // List additional ProGuard rules for the given build type here. By default, // Android Studio creates and includes an empty rules file for you (located // at the root directory of each module). "proguard-rules.pro" ) testProguardFiles( // The proguard files listed here are included in the // test APK only. "test-proguard-rules.pro" ) } } flavorDimensions.add("version") productFlavors { create("flavor1") { ... } create("flavor2") { proguardFile("flavor2-rules.pro") } } }
Groovy
android { ... buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), // List additional ProGuard rules for the given build type here. By default, // Android Studio creates and includes an empty rules file for you (located // at the root directory of each module). 'proguard-rules.pro' testProguardFiles // The proguard files listed here are included in the // test APK only. 'test-proguard-rules.pro' } } flavorDimensions "version" productFlavors { flavor1 { ... } flavor2 { proguardFile 'flavor2-rules.pro' } } }
تقليص حجم التعليمة البرمجية
يتم تلقائيًا تفعيل ميزة تخفيض الرمز باستخدام R8 عند ضبط minifyEnabled
.
على true
.
تقليص التعليمات البرمجية (المعروف أيضًا باسم اهتزاز الشجرة)، هو عملية إزالة الرمز الذي تعتبره R8 غير مطلوبة في وقت التشغيل. يمكن أن تقلل هذه العملية بشكل كبير حجم التطبيق إذا كان، على سبيل المثال، يتضمن العديد من تبعيات المكتبة ولكن تستخدم جزءًا صغيرًا فقط من وظائفها.
لتقليص حجم رمز تطبيقك، يحدّد الإصدار R8 أولاً جميع نقاط الدخول إلى استنادًا إلى مجموعة ملفات الإعداد المدمجة. تشمل نقاط الدخول هذه جميع الفئات التي قد يستخدمها نظام Android لفتح أنشطة تطبيقك أو خدماته بدءًا من كل نقطة دخول، يفحص R8 التعليمات البرمجية لتطبيقك لإنشاء رسم بياني لجميع الطرق ومتغيرات الأعضاء والفئات التي يمكن لتطبيقك الوصول إليها في وقت التشغيل. رمز غير مرتبط بـ يُعد هذا الرسم البياني لا يمكن الوصول إليه وقد تتم إزالته من التطبيق.
يوضِّح الشكل 1 تطبيقًا يعتمد على مكتبة وقت تشغيل. أثناء فحص
رمز التطبيق، تحدِّد R8 أن الطرق foo()
وfaz()
وbar()
هي
من نقطة دخول MainActivity.class
. لكن فئة
عدم استخدام التطبيق OkayApi.class
أو طريقته baz()
مطلقًا في وقت التشغيل
ويزيل الإصدار R8 هذا الرمز عند تصغير تطبيقك.
الشكل 1. في وقت التجميع، تقوم R8 بإنشاء يستند إلى مجموعة قواعد الاحتفاظ بمشروعك الموحّدة لتحديد الرموز التي لا يمكن الوصول إليها.
يحدّد R8 نقاط الدخول من خلال قواعد -keep
في إطار المشروع.
ملفات إعداد R8. أي، اجعل القواعد تحدد
والفئات التي يجب ألا تتجاهلها R8 عند تقليص التطبيق، وتراعي R8
هذه الفئات كنقاط دخول محتملة إلى تطبيقك. المكوّن الإضافي لنظام Gradle المتوافق مع Android
وستنشئ AAPT2 تلقائيًا القواعد التي تطلبها معظم التطبيقات
المشروعات الخاصة بك، مثل أنشطة تطبيقك ومشاهداته وخدماته. ومع ذلك،
إذا كنت بحاجة إلى تخصيص هذا السلوك التلقائي باستخدام قواعد Keep الإضافية، يُرجى الاطّلاع على
هذا القسم المتعلّق بكيفية تخصيص الرمز المطلوب الاحتفاظ به.
إذا كنت مهتمًا فقط بتقليل حجم موارد تطبيقك، الانتقال إلى القسم الخاص بكيفية تقليل الموارد.
لاحظ أنه إذا تم تقليص مشروع مكتبة، فإن تطبيق يعتمد على تلك المكتبة فصول مكتبة صغيرة. قد تحتاج إلى تعديل قواعد الاحتفاظ بالمكتبة في حال هناك صفوف غير متوفّرة في حِزمة APK للمكتبة. إذا كنت تنشئ وتنشر ليست مكتبة بتنسيق AAR، وملفات JAR محلية تعتمد عليها مكتبتك ملف في ملف AAR.
تخصيص الرمز الذي تريد الاحتفاظ به
في معظم الحالات، يكون ملف قواعد ProGuard التلقائي (proguard-android-optimize.txt
)
كافيًا لـ R8 لإزالة الرمز غير المستخدم فقط. ومع ذلك،
يصعب على R8 تحليل بعض المواقف بشكل صحيح وقد تزيل
الرمز الذي يحتاجه تطبيقك. بعض الأمثلة على الحالات التي قد تتم فيها الإزالة بشكل غير صحيح
ما يلي:
- عندما يستدعي تطبيقك إحدى الطرق من واجهة Java الأصلية (JNI)
- عند بحث التطبيق عن الرمز في وقت التشغيل (على سبيل المثال، عند البحث عن الرمز)
من المفترض أن يكشف اختبار تطبيقك عن أي أخطاء ناتجة عن إزالته بشكل غير صحيح. ولكن يمكنك أيضًا فحص الرمز الذي تمت إزالته عن طريق إنشاء تقرير بالرمز البرمجي الذي تمت إزالته.
لإصلاح الأخطاء وإجبار R8 على الاحتفاظ برمز معين، أضف
-keep
سطر في ملف قواعد ProGuard. مثلاً:
-keep public class MyClass
وبدلاً من ذلك، يمكنك إضافة
@Keep
إضافة تعليق توضيحي إلى الرمز البرمجي الذي أدخلته
الاحتفاظ به. تؤدي إضافة @Keep
إلى صف دراسي إلى إبقاء الصف بأكمله كما هو.
ستؤدي إضافته إلى طريقة أو حقل إلى الاحتفاظ بالطريقة/الحقل (واسمه) أيضًا
كاسم الفئة سليمًا. لاحظ أن هذا التعليق التوضيحي لا يتوفر إلا عند استخدام
الـ
مكتبة التعليقات التوضيحية في AndroidX
وعند تضمين ملف قواعد ProGuard ضمن حزمة
المكوّن الإضافي Gradle، كما هو موضح في القسم الخاص بكيفية
إتاحة تقليص البيانات
هناك العديد من الاعتبارات التي يجب مراعاتها عند استخدام خيار "-keep
". حيث
مزيد من المعلومات عن تخصيص ملف القواعد، يُرجى الاطّلاع على
دليل ProGuard:
تشير رسالة الأشكال البيانية
تحديد المشاكل وحلّها
المشكلات الشائعة الأخرى التي قد تواجهها عندما تحصل
تم خلعه.
إزالة المكتبات الأصلية
بشكل تلقائي، تتم إزالة مكتبات الرموز البرمجية الأصلية في إصدارات إصدارات تطبيقك. يتكون هذا التقسيم من إزالة جدول الرموز ومعلومات تصحيح الأخطاء المضمّنة في أي مكتبات أصلية يستخدمها تطبيقك إزالة الرمز الأصلي المكتبات إلى توفير كبير في الحجم؛ إلا أنه من المستحيل تشخيص في Google Play Console بسبب عدم توفر معلومات (مثل أسماء الفئات والدوال).
دعم أعطال الرموز البرمجية الأصلية
تُبلغ أداة Google Play Console عن الأعطال الأصلية ضمن مؤشرات Android الحيوية: مع عدد قليل من يمكنك إنشاء وتحميل ملف أصلي لتصحيح أخطاء الترميز لتطبيقك. ويفعِّل هذا الملف عمليات تتبُّع تسلسُل استدعاء الدوال البرمجية لتعطُّل التطبيق الرموزية (التي تتضمّن الفئة أسماء الدوال) في "مؤشرات Android الحيوية" لمساعدتك على تصحيح أخطاء تطبيقك في مرحلة الإنتاج. تختلف هذه الخطوات حسب إصدار المكوّن الإضافي لنظام Gradle المتوافق مع Android المستخدَم في لمشروعك والمخرجات النهائية لمشروعك.
الإصدار 4.1 من المكوّن الإضافي لنظام Gradle المتوافق مع Android أو إصدار أحدث
إذا كان مشروعك ينشئ مجموعة حزمات تطبيق Android، يمكنك تلقائيًا تضمين
ملف الترميز الأصلي لتصحيح الأخطاء. لتضمين هذا الملف في بُنى الإصدار، أضِف
التالي إلى ملف build.gradle.kts
في تطبيقك:
android.buildTypes.release.ndk.debugSymbolLevel = { SYMBOL_TABLE | FULL }
حدد مستوى رمز تصحيح الأخطاء مما يلي:
- يمكنك استخدام
SYMBOL_TABLE
للحصول على أسماء الوظائف في عمليات تتبُّع تسلسُل استدعاء الدوال البرمجية التي يتم ترميزها في Play Console. يتوافق هذا المستوى مع ملفات Tombstone. - استخدام "
FULL
" للحصول على أسماء الوظائف والملفات وأرقام الأسطر في أداة Play Console عمليات تتبع تسلسل استدعاء الدوال البرمجية التي يتم ترميزها.
إذا كان مشروعك ينشئ حزمة APK، استخدِم إعدادات إصدار "build.gradle.kts
" المعروضة.
سابقًا لإنشاء ملف تصحيح أخطاء الترميز الأصلي بشكل منفصل. يدويًّا
تحميل ملف تصحيح أخطاء الترميز المحلي
إلى Google Play Console. وكجزء من عملية التصميم، يتم استخدام واجهة برمجة التطبيقات Android Gradle
يعمل المكون الإضافي على إخراج هذا الملف في موقع المشروع التالي:
app/build/outputs/native-debug-symbols/variant-name/native-debug-symbols.zip
الإصدار 4.0 من المكوّن الإضافي لنظام Gradle المتوافق مع Android أو الإصدارات الأقدم (وأنظمة التصميم الأخرى)
وكجزء من عملية التصميم، يحتفظ المكوّن الإضافي لنظام Gradle المتوافق مع Android بنسخة من المكتبات التي لم تتم إزالتها في دليل المشروع. تتشابه بنية الدليل هذه مع ما يلي:
app/build/intermediates/cmake/universal/release/obj/
├── armeabi-v7a/
│ ├── libgameengine.so
│ ├── libothercode.so
│ └── libvideocodec.so
├── arm64-v8a/
│ ├── libgameengine.so
│ ├── libothercode.so
│ └── libvideocodec.so
├── x86/
│ ├── libgameengine.so
│ ├── libothercode.so
│ └── libvideocodec.so
└── x86_64/
├── libgameengine.so
├── libothercode.so
└── libvideocodec.so
اضغط محتوى هذا الدليل:
cd app/build/intermediates/cmake/universal/release/obj
zip -r symbols.zip .
يدويًّا تحميل ملف
symbols.zip
إلى Google Play Console.
تقليص مواردك
ولا يعمل تقليص الموارد إلا مع تقليص الرموز. بعد تزيل أداة تقليص التعليمات البرمجية جميع التعليمات البرمجية غير المستخدمة، ويمكن لأداة تقليص الموارد تحديد والموارد التي لا يزال التطبيق يستخدمها. هذا صحيح بشكل خاص عند إضافة تعليمة برمجية مكتبات تتضمن موارد — فيجب إزالة رمز المكتبة غير المستخدَم حتى تصبح موارد المكتبة غير مرجعية، وبالتالي قابلة للإزالة بواسطة المورد جهاز تقليص.
لتفعيل تقليص الموارد، يجب ضبط السمة shrinkResources
.
إلى true
في النص البرمجي للإصدار (بالإضافة إلى
minifyEnabled
لتقليص الرموز). مثلاً:
Kotlin
android { ... buildTypes { getByName("release") { isShrinkResources = true isMinifyEnabled = true proguardFiles( getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" ) } } }
Groovy
android { ... buildTypes { release { shrinkResources true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
إذا لم تكن قد أنشأت تطبيقك باستخدام minifyEnabled
من قبل
لتقليص حجم الرموز، ثم جرّب ذلك قبل تفعيل shrinkResources
،
لأنك قد تحتاج إلى تعديل ملف proguard-rules.pro
إلى
الاحتفاظ بالفئات أو الطرق التي تم إنشاؤها أو استدعاؤها ديناميكيًا قبل
البدء في إزالة الموارد.
تخصيص الموارد التي يجب الاحتفاظ بها
إذا كانت هناك موارد محددة تريد الاحتفاظ بها أو تجاهلها، يمكنك إنشاء ملف XML
ملف في مشروعك بعلامة <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" />
احفظ هذا الملف في موارد مشروعك، على سبيل المثال، على
res/raw/my.package.keep.xml
لا يدمج الإصدار هذا الملف في
التطبيق.
ملاحظة: يُرجى التأكّد من استخدام اسم فريد لملف keep
. فعندما
يتم ربط مكتبات مختلفة معًا فقد تتعارض قواعد Keep
بخلاف ذلك، مما يتسبب في مشكلات محتملة مع القواعد التي يتم تجاهلها أو الاحتفاظ بها
الموارد.
إن تحديد الموارد التي يجب تجاهلها قد يبدو سخيفًا عندما يكون بإمكانك
بدلاً من ذلك، يجب حذفها، ولكن قد يكون ذلك مفيدًا عند استخدام صيغ الإصدار. بالنسبة
على سبيل المثال، يمكنك وضع جميع مواردك في دليل المشروع المشترك،
ثم إنشاء ملف my.package.build.variant.keep.xml
مختلف لكل منها
إصدار متغير عندما تعرف أن موردًا معينًا يبدو مستخدَمًا في التعليمات البرمجية
(وبالتالي لا تتم إزالته بواسطة أداة الكسر)، لكنك تعلم أنه في الواقع لن يتم
يتم استخدامه لصيغة الإصدار المقدَّمة. من الممكن أيضًا أن تتضمن أدوات الإنشاء
أحد الموارد بشكل غير صحيح حسب الحاجة، وهو ما قد يحدث بسبب
يقوم برنامج التحويل البرمجي بمعرفات الموارد المضمنة ومن ثم قد لا
معرفة الفرق بين المورد المشار إليه حقًا وقيمة العدد الصحيح
في التعليمة البرمجية التي تصادف أن تكون لها نفس القيمة.
تفعيل عمليات التحقّق الصارمة من المراجع
عادةً، يمكن لمسؤول تقليص الموارد تحديد ما إذا كان المورد
استخدام المشروع. ومع ذلك، إذا كانت التعليمة البرمجية تتصل
Resources.getIdentifier()
(أو إذا كانت إحدى مكتباتك تتيح ذلك—AppCompat
المكتبة)، فهذا يعني أن الرمز الخاص بك يبحث عن أسماء الموارد بناءً على
سلاسل مُنشأة ديناميكيًا عند القيام بذلك، ستعمل أداة تقليص الموارد
بشكل دفاعي تلقائيًا ووضع علامة على كل الموارد ذات تنسيق اسم مطابق
يُحتمل أن يكون مستخدمًا وغير متاح للإزالة.
على سبيل المثال، تتسبب التعليمة البرمجية التالية في جعل جميع الموارد التي تشتمل على
يجب وضع علامة "مستخدَمة" على بادئة img_
.
Kotlin
val name = String.format("img_%1d", angle + 1) val res = resources.getIdentifier(name, "drawable", packageName)
Java
String name = String.format("img_%1d", angle + 1); res = getResources().getIdentifier(name, "drawable", getPackageName());
تبحث أداة تقليص الموارد أيضًا في جميع ثوابت السلسلة في
بالإضافة إلى موارد res/raw/
المتنوعة التي تبحث عن
عناوين URL بتنسيق يشبه
file:///android_res/drawable//ic_plus_anim_016.png
إذا وجدت
سلاسل مثل هذه أو غيرها، والتي تبدو وكأنها يمكن استخدامها لإنشاء عناوين URL
هكذا، فإنه لا يزيلها.
في ما يلي أمثلة على "وضع التقلّص الآمن" الذي يتم تفعيله تلقائيًا.
مع ذلك، يُرجى إيقاف هذا الخيار. ومعالجتها وتحديد
بحيث يحتفظ جهاز تقليص الموارد بالموارد المستخدمة بالتأكيد. إلى
إجراء ذلك، ضبط shrinkMode
على strict
في
keep.xml
على النحو التالي:
<?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:shrinkMode="strict" />
إذا قمت بتفعيل وضع الانكماش الصارم، وكانت التعليمات البرمجية تشير أيضًا إلى
بسلاسل تم إنشاؤها ديناميكيًا، كما هو موضح أعلاه، فيجب عليك
الاحتفاظ بهذه الموارد يدويًا باستخدام سمة tools:keep
إزالة الموارد البديلة غير المستخدَمة
تزيل أداة تقليم موارد Gradle فقط الموارد غير المشار إليها
بواسطة رمز التطبيق، مما يعني أنه لن تتم إزالة
موارد بديلة لإعدادات الأجهزة المختلفة. إذا لزم الأمر،
يمكنك استخدام السمة resConfigs
في المكوّن الإضافي لنظام Gradle المتوافق مع Android
إزالة ملفات الموارد البديلة التي لا يحتاجها تطبيقك.
فعلى سبيل المثال، إذا كنت تستخدم مكتبة تتضمن موارد لغوية
(مثل AppCompat أو خدمات Google Play)، فسيتضمن تطبيقك جميع
سلاسل اللغة المترجمة للرسائل في تلك المكتبات سواء كانت
عندما تتم ترجمة بقية محتوى التطبيق إلى اللغات نفسها أو لا. إذا كنت ترغب في
تتيح لك الاحتفاظ باللغات التي يتيحها تطبيقك رسميًا، يمكنك تحديد
هذه اللغات باستخدام السمة resConfig
. أي موارد
تتم إزالة اللغات غير المحددة.
يعرض المقتطف التالي كيفية حصر موارد اللغة على الإنجليزية والفرنسية:
Kotlin
android { defaultConfig { ... resourceConfigurations.addAll(listOf("en", "fr")) } }
Groovy
android { defaultConfig { ... resConfigs "en", "fr" } }
عند إصدار تطبيق باستخدام تنسيق "مجموعة حزمات تطبيق Android"، يتم ذلك تلقائيًا فقط يتم تنزيل اللغات التي تم ضبطها على جهاز المستخدم عند تثبيت التطبيق. وبالمثل، لا تتوفّر إلا الموارد التي تتطابق مع كثافة شاشة الجهاز، والموارد الأصلية يتم تضمين المكتبات المطابقة لواجهة التطبيق الثنائية (ABI) للجهاز في عملية التنزيل. لمزيد من المعلومات، المعلومات تشير إلى تطبيق Android إعداد الحزمة:
بالنسبة إلى التطبيقات القديمة التي يتم إصدارها باستخدام حِزم APK (التي تم إنشاؤها قبل آب (أغسطس) 2021)، يمكنك: تخصيص كثافة الشاشة أو موارد ABI المراد تضمينها في حزمة APK من خلال إنشاء حِزم APK متعدّدة أن يستهدف كل منها تهيئة جهاز مختلفة.
دمج الموارد المكرّرة
بشكل افتراضي، تدمج Gradle أيضًا الموارد ذات الأسماء المتطابقة، مثل
عناصر قابلة للرسم بالاسم ذاته والتي قد تكون في مجلدات موارد مختلفة. هذا النمط
لا يتم التحكم في السلوك من خلال السمة shrinkResources
لا يمكن إيقافه، لأنه من الضروري تجنب الأخطاء عند تعدد
تتطابق مع الاسم الذي تبحث عنه التعليمة البرمجية.
لا يحدث دمج الموارد إلا عندما يتشارك ملفان أو أكثر في البيانات ذات واسم المورد ونوعه ومؤهِّله. تختار Gradle الملف الذي يراعيه أن تكون أفضل خيار من بين النسخ المكررة (بناءً على ترتيب الأولوية الموضح أدناه) ولا تمرر إلا هذا المورد الواحد إلى AAPT للتوزيع في الأداة النهائية.
يبحث Gradle عن موارد مكررة في المواقع التالية:
- تتضمن الموارد الرئيسية المرتبطة بمجموعة المصدر الرئيسية بشكل عام
تقع في
src/main/res/
. - يمكنك إنشاء نُسخ مختلفة من المنتج، بدءًا من نوع التصميم ونكهات التصميم.
- تبعيات مشروع المكتبة.
تدمج Gradle الموارد المكررة بالترتيب الأول المتتالي التالي:
التبعيات ← الأساسي ← بناء النكهة ← نوع الإصدار
على سبيل المثال، في حالة ظهور مورد مكرر في كل من مواردك الرئيسية نكهة بناء، فإن Gradle تختار نكهة الإنشاء.
إذا ظهرت موارد متطابقة في مجموعة المصادر نفسها، سيتعذّر دمج Gradle
وينتج عن ذلك خطأ دمج الموارد. يمكن أن يحدث هذا إذا قمت بتحديد عدة
مجموعات المصادر في الموقع sourceSet
في
ملف build.gradle.kts
- على سبيل المثال، إذا كانت الخدمتان src/main/res/
وsrc/main/res2/
يحتويان على موارد متطابقة.
تشويش التعليمات البرمجية
والغرض من التشويش هو تقليل حجم التطبيق من خلال اختصار أسماء فئات تطبيقك وأساليبه وحقوله فيما يلي مثال على التشويش باستخدام R8:
androidx.appcompat.app.ActionBarDrawerToggle$DelegateProvider -> a.a.a.b:
androidx.appcompat.app.AlertController -> androidx.appcompat.app.AlertController:
android.content.Context mContext -> a
int mListItemLayout -> O
int mViewSpacingRight -> l
android.widget.Button mButtonNeutral -> w
int mMultiChoiceItemLayout -> M
boolean mShowTitle -> P
int mViewSpacingLeft -> j
int mButtonPanelSideLayout -> K
على الرغم من أنّ التشويش لا يزيل الرمز البرمجي من تطبيقك، يتم توفير حجم كبير يظهر في التطبيقات التي تحتوي على ملفات DEX التي تفهرس العديد من الفئات والطرق والحقول. ومع ذلك، ونظرًا لأن التشويش يعيد تسمية أجزاء مختلفة من التعليمات البرمجية، فقد يتم مثل فحص تتبعات تسلسل استدعاء الدوال البرمجية، يتطلب ذلك أدوات إضافية. لفهم تتبع تسلسل استدعاء الدوال البرمجية بعد إخفاء مفاتيح فك التشفير، فاقرأ القسم الخاص بكيفية فك ترميز تتبُّع تسلسل استدعاء الدوال البرمجية مع تشويش.
بالإضافة إلى ذلك، إذا كانت التعليمات البرمجية تعتمد على تسمية يمكن توقعها لأساليب تطبيقك والفئات — عند استخدام الانعكاس، على سبيل المثال، ينبغي أن تتعامل مع تلك التوقيعات كنقاط دخول وتحديد قواعد الاحتفاظ بها، كما هو موضح في حول كيفية تخصيص الرمز المطلوب الاحتفاظ به. cannot translate توجّه R8 المستخدمين إلى الاحتفاظ بهذه الرموز في دالة DEX النهائية الخاصة بتطبيقك، بل سيحتفظون بها أيضًا. اسمه الأصلي.
فك ترميز عملية تتبُّع تسلسل استدعاء الدوال البرمجية التي تم تشويشها
بعد تشويش R8 على الرمز البرمجي، سيكون من الصعب فهم عملية تتبُّع تسلسل استدعاء الدوال البرمجية. (إذا لم يكن مستحيلاً) لأن أسماء الفئات والأساليب ربما كانت بتغييره. للحصول على تقرير تتبُّع تسلسل استدعاء الدوال البرمجية الأصلي، يجب تتبُّع عملية تتبُّع تسلسل استدعاء الدوال البرمجية.
تحسين الرمز
ولتحسين تطبيقك بشكل أكبر، يفحص R8 التعليمات البرمجية لديك بشكل أعمق لإزالة المزيد من التعليمات البرمجية غير المستخدمة أو إعادة كتابة التعليمات البرمجية قدر الإمكان فإنها أقل طولاً. في ما يلي بعض الأمثلة على هذه التحسينات:
- إذا لم يستخدم الرمز فرع
else {}
لعبارة if/else محددة مطلقًا، قد يزيل R8 الرمز لفرعelse {}
. - إذا يستدعي الرمز طريقة في عدد قليل من الأماكن فقط، قد يزيل R8 الطريقة وإدراجه في مواقع الاتصال القليلة.
- إذا حددت R8 أن فئة ما بها فئة فرعية واحدة فريدة فقط، نفسها لا يتم إنشاء مثيل لها (على سبيل المثال، فئة أساس مجردة تستخدمها فقط فئة تنفيذ ملموسة)، فيمكن لـ R8 أن تجمع بين الفئتين إزالة فئة من التطبيق.
- لمزيد من المعلومات، يُرجى قراءة مشاركات مدوّنة تحسين R8 من تأليف "جيك وارتون".
لا تسمح لك R8 بإيقاف أو تمكين تحسينات منفصلة أو تعديل
طريقة التحسين. في الواقع، يتجاهل R8 أي قواعد ProGuard تحاول
لتعديل التحسينات التلقائية، مثل -optimizations
-optimizationpasses
هذا القيد مهم لأنه، حيث تستمر R8 في
التحسين المستمر، والحفاظ على سلوك عادي للتحسينات، يساعد نظام
يمكن لفريق الاستوديو تحديد المشاكل وحلّها بسهولة وحلّ أي مشاكل قد تواجهها.
تجدر الإشارة إلى أنّ تفعيل التحسين سيؤدي إلى تغيير عمليات تتبُّع تسلسل استدعاء الدوال البرمجية في التطبيق. على سبيل المثال، سيؤدي الإدخال إلى إزالة إطارات تسلسل استدعاء الدوال البرمجية. راجع القسم الذي يتناول retracing لمعرفة كيفية الحصول على عمليات تتبُّع تسلسل استدعاء الدوال البرمجية الأصلية.
التأثير في أداء بيئة التشغيل
في حال تفعيل كلّ من عناصر تصغير البيانات والتشويش والتحسين، سيتم تحسين R8. أداء وقت تشغيل الرمز البرمجي (بما في ذلك وقت بدء التشغيل ووقت عرض اللقطة في سلسلة واجهة المستخدم) بنسبة تصل إلى %30 يؤدي إيقاف أي من هذه الإجراءات إلى تقييد مجموعة التحسينات بشكل كبير استخدامات R8.
إذا تم تمكين R8، فيجب عليك أيضًا إنشاء الملفات الشخصية للشركات الناشئة لتحسين أداء الشركات الناشئة.
تفعيل تحسينات أكثر صرامة
تتضمن R8 مجموعة من التحسينات الإضافية (المشار إليها باسم "الوضع الكامل") التي يجعله يتصرف بشكل مختلف عن ProGuard. تم تفعيل هذه التحسينات من خلال تلقائي منذ الإصدار 8.0.0 من المكوّن الإضافي لنظام Gradle المتوافق مع Android
يمكنك إيقاف هذه التحسينات الإضافية من خلال تضمين ما يلي في
ملف gradle.properties
لمشروعك:
android.enableR8.fullMode=false
ولأن التحسينات الإضافية تجعل R8 تتصرف بشكل مختلف عن ProGuard، قد تتطلب منك تضمين قواعد ProGuard إضافية لتجنب وقت التشغيل إذا كنت تستخدم قواعد مصمَّمة لـ ProGuard. على سبيل المثال، لنفترض أن إلى فئة من خلال واجهة برمجة تطبيقات Java Reclection. عند عدم استخدام و"الوضع الكامل" يفترض R8 أنك تعتزم فحص كائنات هذه الفئة في وقت التشغيل - حتى لو لم يحدث ذلك في الرمز - ويتم تحتفظ بالفئة ومهيئها الثابت.
ومع ذلك، عند استخدام "الوضع الكامل"، فإن R8 لا تضع هذا الافتراض، وإذا كانت R8 أن التعليمات البرمجية لا تستخدم الفئة أبدًا في وقت التشغيل، فإن ذلك يؤدي إلى الفئة من دالة DEX النهائية لتطبيقك. أي، إذا كنت تريد الاحتفاظ بالفئة برنامج التهيئة الثابت، يلزمك تضمين قاعدة Keep في ملف القواعد لتنفيذه ذلك.
إذا واجهت أي مشاكل أثناء استخدام "الوضع الكامل" في R8، فراجع صفحة الأسئلة الشائعة حول R8 للعثور على حل ممكن. إذا تعذّر عليك حلّ المشكلة، يُرجى الإبلاغ عن خطأ.
جارٍ تتبُّع عمليات تتبُّع تسلسل استدعاء الدوال البرمجية
يتم تغيير التعليمة البرمجية التي تمت معالجتها بواسطة R8 بطرق مختلفة يمكن أن تجعل عمليات تتبع تسلسل استدعاء الدوال البرمجية. يصعب فهمه لأن عمليات تتبُّع تسلسل استدعاء الدوال البرمجية لن تتطابق تمامًا مع رمز المصدر. هذا النمط في حالة التغييرات على أرقام الأسطر عند حدوث لم يتم الاحتفاظ بها. وقد يرجع ذلك إلى تحسينات مثل التضمين والتحديد. تشير رسالة الأشكال البيانية والمساهم الأكبر هو إخفاء مفاتيح فك التشفير، حتى أن الفئات والأساليب تغيير الأسماء.
لاسترداد تتبع التكديس الأصلي، توفر R8 retrace، وهي مرفقة مع حزمة أدوات سطر الأوامر.
لإتاحة تتبع عمليات تتبع تسلسل استدعاء الدوال البرمجية في التطبيق، يجب التأكد من
تحتفظ النسخة بمعلومات كافية لتتبعها عن طريق إضافة ما يلي
إلى ملف proguard-rules.pro
في وحدتك:
-keepattributes LineNumberTable,SourceFile
-renamesourcefileattribute SourceFile
تحتفظ السمة LineNumberTable
بمعلومات الموضع
في طرق تتم فيها طباعة هذه المواضع في عمليات تتبع تسلسل استدعاء الدوال البرمجية. السمة SourceFile
يضمن طباعة المعلومات الموضعية في جميع بيئات التشغيل المحتملة.
يضبط التوجيه -renamesourcefileattribute
اسم الملف المصدر في الحزمة
يُعد آثارًا إلى SourceFile
فقط. اسم ملف المصدر الأصلي الفعلي ليس
تكون مطلوبة عند إعادة التتبع لأن ملف التعيين يحتوي على ملف المصدر الأصلي.
ينشئ R8 ملف mapping.txt
في كل مرة يتم فيها تشغيله، وهو ما
يحتوي على المعلومات اللازمة لإعادة ربط عمليات تتبُّع تسلسل استدعاء الدوال البرمجية بالنسخة الأصلية.
عمليات تتبع تسلسل استدعاء الدوال البرمجية. يحفظ "استوديو Android" الملف في
<module-name>/build/outputs/mapping/<build-type>/
الدليل.
عند نشر تطبيقك على Google Play، يمكنك تحميل ملف mapping.txt
.
لكل إصدار من إصدارات تطبيقك عند النشر باستخدام مجموعة حزمات تطبيق Android، يجب مراعاة التالي
تلقائيًا كجزء من محتوى حِزمة التطبيق. ثم Google
سيتتبّع Play عمليات تتبُّع تسلسُل استدعاء الدوال البرمجية الواردة من المشاكل التي أبلغ عنها المستخدم كي تتمكّن من
مراجعتها في Play Console. لمزيد من المعلومات، يُرجى الانتقال إلى "مركز المساعدة".
مقالة حول كيفية
إزالة تشويش عمليات تتبُّع تسلسل استدعاء الدوال البرمجية لتعطُّل التطبيق.
تحديد المشاكل وحلّها باستخدام الإصدار R8
يصف هذا القسم بعض الاستراتيجيات لتحديد المشاكل وحلّها عند تفعيل هذه الميزة. والتقليص والتشويش والتحسين باستخدام R8. إذا لم تجد حلاً على مشكلتك أدناه، يُرجى أيضًا قراءة صفحة الأسئلة الشائعة حول R8 أو دليل تحديد المشاكل وحلّها في ProGuard
إنشاء تقرير للرمز البرمجي الذي تمت إزالته (أو الاحتفاظ به)
لمساعدتك في استكشاف بعض مشكلات R8 وإصلاحها، قد يكون من المفيد الاطلاع على تقرير عن
كل التعليمات البرمجية التي أزالها R8 من تطبيقك. لكل وحدة تريد استخدامها
لإنشاء هذا التقرير، أضِف -printusage <output-dir>/usage.txt
إلى حسابك المخصّص.
ملف القواعد. عند تفعيل R8 وإنشاء تطبيقك، تُخرج R8
بالمسار واسم الملف اللذين حددتهما. تقرير الرمز الذي تمت إزالته
يبدو مشابهًا لما يلي:
androidx.drawerlayout.R$attr
androidx.vectordrawable.R
androidx.appcompat.app.AppCompatDelegateImpl
public void setSupportActionBar(androidx.appcompat.widget.Toolbar)
public boolean hasWindowFeature(int)
public void setHandleNativeActionModesEnabled(boolean)
android.view.ViewGroup getSubDecor()
public void setLocalNightMode(int)
final androidx.appcompat.app.AppCompatDelegateImpl$AutoNightModeManager getAutoNightModeManager()
public final androidx.appcompat.app.ActionBarDrawerToggle$Delegate getDrawerToggleDelegate()
private static final boolean DEBUG
private static final java.lang.String KEY_LOCAL_NIGHT_MODE
static final java.lang.String EXCEPTION_HANDLER_MESSAGE_SUFFIX
...
إذا كنت تريد بدلاً من ذلك مشاهدة تقرير بنقاط الدخول التي تحددها R8 من
حافِظ على القواعد الخاصة بمشروعك، وضمِّن -printseeds <output-dir>/seeds.txt
في
ملف القواعد المخصصة. عند تفعيل R8 وإنشاء تطبيقك، تُخرج R8 النتائج.
تقرير باسم المسار واسم الملف اللذين حددتهما. تقرير الإدخال الذي تم الاحتفاظ به
النقاط مشابهة لما يلي:
com.example.myapplication.MainActivity
androidx.appcompat.R$layout: int abc_action_menu_item_layout
androidx.appcompat.R$attr: int activityChooserViewStyle
androidx.appcompat.R$styleable: int MenuItem_android_id
androidx.appcompat.R$styleable: int[] CoordinatorLayout_Layout
androidx.lifecycle.FullLifecycleObserverAdapter
...
تحديد المشاكل المتعلّقة بتقليل الموارد وحلّها
عند تقليص الموارد، يؤدي دور إنشاء
تُظهر ملخصًا
الموارد التي تمت إزالتها من التطبيق. (عليك أولاً النقر على تبديل العرض.
على الجانب الأيسر من النافذة لعرض إخراج نص تفصيلي من 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
"
يمكن الوصول إليها، فإذا بحثت لأعلى ستجد هذا المورد مُدرجًا
ضمن "الموارد الجذر التي يمكن الوصول إليها هي:". وهذا يعني أن هناك مرجعًا للتعليمات البرمجية
إلى add_schedule_fab_icon_anim
(أي أن رقم تعريف R.drawable كان
الموجودة في الرمز الذي يمكن الوصول إليه).
إذا لم تكن تستخدم عملية تحقق متشددة، يمكن وضع علامة على أرقام تعريف الموارد على أنّها قابلة للوصول إليها. إذا كانت هناك ثوابت سلسلة تبدو وكأنها يمكن استخدامها لإنشاء أسماء الموارد للموارد التي يتم تحميلها ديناميكيًا. في هذه الحالة، إذا بحثت ناتج الإصدار لاسم المورد، قد تجد رسالة مثل هذه:
10:32:50.590 [QUIET] [system.out] Marking drawable:ic_plus_anim_016:2130837506
used because it format-string matches string pool constant ic_plus_anim_%1$d.
إذا رأيت إحدى هذه السلاسل وكنت متأكدًا من أن السلسلة ليست
لتحميل المورد المحدد بشكل ديناميكي، يمكنك استخدام
tools:discard
لإعلام نظام التصميم بإزالتها
كما هو موضَّح في القسم المتعلّق بكيفية تخصيص الموارد التي يجب الاحتفاظ بها.