في عملية تطوير تطبيقات Android الحديثة، يُعدّ توفير تطبيق صغير وسريع وآمن من التوقعات الأساسية للمستخدمين. الأداة الأساسية التي يستخدمها نظام تصميم Android لتحقيق ذلك هي أداة التحسين R8 ، وهي برنامج التجميع الذي يتعامل مع الرموز غير المستخدَمة وإزالة الموارد لتقليل الحجم، وإعادة تسمية الرموز أو إزالة البيانات غير الضرورية، وتحسين التطبيق.
يُعدّ تفعيل R8 خطوة مهمة في إعداد تطبيق للإصدار، ولكنّه يتطلّب من المطوّرين تقديم إرشادات في شكل "قواعد الاحتفاظ".
بعد قراءة هذه المقالة، يمكنك مشاهدة فيديو "أسبوع تسليط الضوء على الأداء" حول تفعيل أداة تحسين R8 وتصحيح أخطائها وحلّ مشاكلها على YouTube.
أهمية قواعد الاحتفاظ بالبيانات
تنشأ الحاجة إلى كتابة قواعد Keep Rules من تعارض أساسي: R8 هي أداة تحليل ثابت، ولكن تطبيقات Android تعتمد غالبًا على أنماط التنفيذ الديناميكي، مثل الانعكاس أو عمليات الاستدعاء داخل الرمز البرمجي الأصلي وخارجه باستخدام JNI (واجهة Java الأصلية).
ينشئ R8 رسمًا بيانيًا للرمز المستخدَم من خلال تحليل عمليات الاستدعاء المباشر. وعند الوصول إلى الرمز بطريقة ديناميكية، لا يمكن للتحليل الثابت في R8 توقّع ذلك، وسيصنّف هذا الرمز على أنّه غير مستخدَم ويزيله، ما يؤدي إلى حدوث أعطال أثناء وقت التشغيل.
قاعدة الحفاظ على البيانات هي تعليمات صريحة لمترجم R8، تنص على ما يلي: "هذا الصنف أو الطريقة أو الحقل المحدّد هو نقطة دخول سيتم الوصول إليها بشكل ديناميكي في وقت التشغيل. يجب الحفاظ عليه، حتى إذا لم تتمكّن من العثور على مرجع مباشر إليه".
يمكنك الاطّلاع على الدليل الرسمي لمعرفة المزيد من التفاصيل حول قواعد الاحتفاظ.
مكان كتابة "قواعد الاحتفاظ"
تتم كتابة قواعد الاحتفاظ المخصّصة لأحد التطبيقات في ملف نصي. وفقًا للاصطلاح، يُطلق على هذا الملف الاسم proguard-rules.pro ويقع في جذر وحدة التطبيق أو المكتبة. يتم بعد ذلك تحديد هذا الملف في نوع التصميم release من ملف build.gradle.kts في الوحدة.
release {
isShrinkResources = true
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}استخدام الملف التلقائي الصحيح
تستورد الطريقة getDefaultProguardFile مجموعة تلقائية من القواعد التي توفّرها حزمة تطوير البرامج (SDK) لنظام التشغيل Android. عند استخدام ملف غير صحيح، قد لا يكون تطبيقك محسَّنًا. احرص على استخدام proguard-android-optimize.txt. يوفر هذا الملف "قواعد الاحتفاظ" التلقائية لمكوّنات Android العادية ويتيح تحسينات R8 على الرموز. لا يوفّر الإصدار القديم من proguard-android.txt سوى قواعد Keep، ولكنه لا يفعّل تحسينات R8.
بما أنّ هذه المشكلة تؤثر بشكل كبير في الأداء، سنبدأ في تحذير المطوّرين بشأن استخدام الملف غير الصحيح، وذلك بدءًا من الإصدار 3 من ميزة Narwhal في "استوديو Android". واعتبارًا من الإصدار 9.0 من "المكوّن الإضافي لنظام Gradle المتوافق مع Android"، لن نتيح استخدام الملف proguard-android.txt القديم، لذا احرص على الترقية إلى الإصدار المحسّن.
كيفية كتابة قواعد Keep
تتألف قاعدة الحفظ من ثلاثة أجزاء رئيسية:
- خيار مثل
-keepأو-keepclassmembers - المعدّلات الاختيارية مثل
allowshrinking - مواصفات فئة تحدّد الرمز المطلوب مطابقته
للاطّلاع على البنية الكاملة والأمثلة، يُرجى الرجوع إلى الإرشادات حول إضافة قواعد الاحتفاظ.
مضادات أنماط قواعد الاحتفاظ بالبيانات
من المهم معرفة أفضل الممارسات، ولكن من المهم أيضًا معرفة الأنماط المضادة، لأنّ هذه الأنماط غالبًا ما تنشأ عن سوء فهم أو اختصارات لتحديد المشاكل وحلّها، ويمكن أن تكون كارثية على أداء الإصدار المتاح للجميع.
الخيارات العامّة
هذه العلامات هي مفاتيح تبديل عامة يجب عدم استخدامها مطلقًا في بنية الإصدار، بل تُستخدَم فقط لتصحيح الأخطاء مؤقتًا بهدف تحديد المشكلة.
يؤدي استخدام -dontotptimize إلى إيقاف تحسينات الأداء التي توفّرها الأداة R8، ما يؤدي إلى إبطاء التطبيق.
عند استخدام -dontobfuscate، يتم إيقاف جميع عمليات إعادة التسمية، وعند استخدام -dontshrink، يتم إيقاف إزالة الرموز البرمجية غير النشطة. تؤدي كلتا القاعدتين العامّتين إلى زيادة حجم التطبيق.
تجنَّب استخدام هذه العلامات العامة في بيئة التشغيل الفعلي قدر الإمكان للحصول على تجربة أفضل للمستخدمين.
قواعد الاحتفاظ الواسعة النطاق بشكل مفرط
أسهل طريقة لإبطال مزايا R8 هي كتابة قواعد Keep واسعة النطاق. قواعد Keep، مثل القاعدة أدناه، توجّه أداة التحسين R8 إلى عدم تصغير أي فئة في هذه الحزمة أو أي من حِزمها الفرعية أو تشويشها أو تحسينها. يؤدي ذلك إلى إزالة مزايا R8 بالكامل لهذه الحزمة بأكملها. حاوِل كتابة قواعد Keep ضيقة ومحدّدة بدلاً من ذلك.
-keep class com.example.package.** { *;} // WIDE KEEP RULES CAUSE PROBLEMSعامل العكس (!)
يبدو أنّ عامل النفي (!) هو طريقة فعّالة لاستبعاد حزمة من إحدى القواعد. لكنّ الأمر ليس بهذه البساطة. لِنأخذ المثال التالي:
-keep class !com.example.my_package.** { *; } // USE WITH CAUTIONقد تعتقد أنّ هذه القاعدة تعني "عدم الاحتفاظ بالفئات فيcom.example.package"، ولكنّها تعني في الواقع "الاحتفاظ بكل فئة وطريقة وسمة في التطبيق بأكمله غير موجودة في com.example.package". إذا كان ذلك مفاجئًا لك، من الأفضل التحقّق من أي عمليات نفي في إعدادات R8.
قواعد مكرّرة لمكوّنات Android
هناك خطأ شائع آخر وهو إضافة "قواعد الإبقاء" يدويًا إلى Activities أو Services أو BroadcastReceivers في تطبيقك، وهذا الإجراء غير ضروري، لأنّ ملف proguard-android-optimize.txt التلقائي يتضمّن القواعد ذات الصلة لكي تعمل هذه المكوّنات العادية في Android بدون أي إعدادات إضافية.
توفّر العديد من المكتبات أيضًا "قواعد الاحتفاظ" الخاصة بها، لذا لن تحتاج إلى كتابة قواعدك الخاصة لهذه المكتبات. وفي حال حدوث مشكلة في "قواعد الاحتفاظ" من مكتبة تستخدمها، من الأفضل التواصل مع مؤلف المكتبة لمعرفة سبب المشكلة.
أفضل الممارسات المتعلّقة بقاعدة Keep
بعد أن عرفت ما لا يجب فعله، لنتحدّث عن أفضل الممارسات.
كتابة "قواعد Keep" محدّدة
يجب أن تكون قواعد الاحتفاظ الجيدة ضيقة ومحدّدة قدر الإمكان، ويجب أن تحتفظ فقط بما هو ضروري، ما يسمح لبرنامج R8 بتحسين كل شيء آخر.
| القاعدة | الجودة |
|---|---|
| منخفض: يتم الاحتفاظ بالحزمة بأكملها وحِزمها الفرعية |
| منخفض: يحتفظ بفئة كاملة من المرجّح أنّها لا تزال واسعة جدًا |
-keepclassmembers class com.example.MyClass {
private java.lang.String secretMessage;
public void onNativeEvent(java.lang.String);
} | عالية: يتم الاحتفاظ بالطرق والسمات ذات الصلة فقط من فئة معيّنة |
استخدام الأسلاف المشتركين
بدلاً من كتابة قواعد Keep منفصلة لنماذج بيانات مختلفة متعددة، اكتب قاعدة واحدة تستهدف صنفًا أساسيًا أو واجهة مشتركة. تطلب القاعدة أدناه من R8 الاحتفاظ بأي عناصر من الفئات التي تنفّذ هذه الواجهة، وهي قابلة للتوسيع بشكل كبير.
# Keep all fields of any class that implements SerializableModel
-keepclassmembers class * implements com.example.models.SerializableModel {
<fields>;
}استخدام التعليقات التوضيحية لاستهداف صفوف متعددة
أنشئ تعليقًا توضيحيًا مخصّصًا (مثل @Serialize) واستخدِمه "لوضع علامة" على الفئات التي تحتاج إلى الاحتفاظ بحقولها. هذا نمط آخر واضح وتصريحي وقابل للتوسّع بشكل كبير. يمكنك إنشاء قواعد Keep للتعليقات التوضيحية الحالية من الأُطر التي تستخدمها أيضًا.
# Keep all fields of any class annotated with @Serialize
-keepclassmembers class * {
@com.example.annotations.Serialize <fields>;
}اختيار خيار Keep المناسب
يُعدّ خيار "الاحتفاظ" الجزء الأكثر أهمية في القاعدة، إذ يمكن أن يؤدي اختيار الخيار الخاطئ إلى إيقاف التحسين بدون داعٍ.
| خيار الاحتفاظ | الإجراءات التي ينفّذها |
-keep | يمنع إزالة الفئة والأعضاء المذكورين في البيان أو إعادة تسميتهم. |
-keepclassmembers | يمنع الأعضاء المحدّدين من إزالتهم أو إعادة تسميتهم، ولكنّه يسمح بإزالة الصف نفسه فقط في الصفوف التي لم تتم إزالتها بطريقة أخرى. |
-keepclasseswithmembers | الدمج: يتم الاحتفاظ بالفئة وعناصرها فقط إذا كانت جميع العناصر المحدّدة متوفّرة. |
يمكنك الاطّلاع على مزيد من المعلومات حول خيار "الاحتفاظ" في مستندات خيارات الاحتفاظ.
السماح بالتحسين باستخدام أدوات التعديل
تخفّف المعدِّلات، مثل allowshrinking وallowobfuscation، من قيود قاعدة -keep الواسعة، ما يتيح لأداة R8 إمكانية التحسين. على سبيل المثال، إذا كانت مكتبة قديمة تفرض عليك استخدام -keep على فئة بأكملها، قد تتمكّن من استعادة بعض التحسينات من خلال السماح بالتصغير والتشويش:
# Keep this class, but allow R8 to remove it if it's unused and allow R8 to rename it. -keep,allowshrinking,allowobfuscation class com.example.LegacyClass
إضافة خيارات عامة لتحسين الأداء بشكل إضافي
بالإضافة إلى "قواعد الاحتفاظ"، يمكنك إضافة علامات عامة إلى ملف إعدادات R8 لتشجيع المزيد من التحسين.
-repackageclasses هو خيار قوي يوجّه أداة R8 إلى نقل جميع الفئات التي تم تشويشها إلى حزمة واحدة، ما يؤدي إلى توفير مساحة كبيرة في ملف DEX من خلال إزالة سلاسل أسماء الحزم المكرّرة.
تسمح -allowaccessmodification لبرنامج R8 بتوسيع نطاق الوصول (على سبيل المثال، من private إلى public) لتفعيل التضمين الأكثر فعالية. يتم تفعيل هذا الخيار تلقائيًا عند استخدام proguard-android-optimize.txt.
تحذير: يجب على مطوّري المكتبات عدم إضافة علامات التحسين العامة هذه إلى قواعد المستهلكين، لأنّه سيتم تطبيقها بشكل إلزامي على التطبيق بأكمله.
ولزيادة الوضوح، سنبدأ في الإصدار 9.0 من المكوّن الإضافي لنظام Gradle المتوافق مع Android بتجاهل علامات التحسين العامة من المكتبات تمامًا.
أفضل الممارسات للمكتبات
يعتمد كل تطبيق Android على المكتبات بطريقة أو بأخرى. لنتحدّث الآن عن أفضل الممارسات المتعلّقة بالمكتبات.
لمطوّري المكتبات
إذا كانت مكتبتك تستخدم الانعكاس أو JNI، تقع على عاتقك مسؤولية توفير قواعد Keep اللازمة للمستهلكين، ويتم وضع هذه القواعد في ملف consumer-rules.pro، ثم يتم تجميعها تلقائيًا داخل ملف AAR الخاص بالمكتبة.
android {
defaultConfig {
consumerProguardFiles("consumer-rules.pro")
}
...
}لمستخدمي المكتبة
فلترة "قواعد Keep" التي تتضمّن مشاكل
إذا كان عليك استخدام مكتبة تتضمّن قواعد Keep Rules إشكالية، يمكنك فلترتها في ملف build.gradle.kts بدءًا من الإصدار 9.0 من AGP، ما يطلب من R8 تجاهل القواعد الواردة من اعتمادية معيّنة.
release {
optimization.keepRules {
// Ignore all consumer rules from this specific library
it.ignoreFrom("com.somelibrary:somelibrary")
}
}أفضل قاعدة احتفاظ هي عدم وجود قاعدة احتفاظ
تتمثّل استراتيجية إعدادات R8 النهائية في إزالة الحاجة إلى كتابة قواعد الاحتفاظ تمامًا. يمكن تحقيق ذلك في العديد من التطبيقات من خلال اختيار مكتبات حديثة تعطي الأولوية لإنشاء الرموز على التفكير المجرد. باستخدام ميزة إنشاء الرموز البرمجية، يمكن لأداة التحسين تحديد الرموز البرمجية المستخدَمة فعليًا في وقت التشغيل والرموز البرمجية التي يمكن إزالتها بسهولة أكبر. عدم استخدام أي انعكاس ديناميكي يعني أيضًا عدم وجود نقاط دخول "مخفية"، وبالتالي لا حاجة إلى قواعد Keep. عند اختيار مكتبة جديدة، ننصحك دائمًا باختيار حلّ يستخدم إنشاء الرموز البرمجية بدلاً من الانعكاس.
لمزيد من المعلومات حول كيفية اختيار المكتبات، يُرجى الاطّلاع على مقالة اختيار المكتبة بحكمة.
تحديد المشاكل وحلّها في إعدادات R8
عندما يزيل R8 رمزًا كان من المفترض أن يحتفظ به، أو إذا كان حجم حزمة APK أكبر من المتوقع، استخدِم هذه الأدوات لتشخيص المشكلة.
البحث عن قواعد Keep المكرّرة والعامة
بما أنّ R8 يدمج القواعد من عشرات المصادر، قد يصعب معرفة مجموعة القواعد "النهائية". تؤدي إضافة هذا الخيار إلى ملف proguard-rules.pro إلى إنشاء تقرير كامل:
# Outputs the final, merged set of rules to the specified file -printconfiguration build/outputs/logs/configuration.txt
يمكنك البحث في هذا الملف للعثور على قواعد مكرّرة أو تتبُّع قاعدة تتضمّن مشكلة (مثل -dontoptimize) والرجوع إلى المكتبة المحدّدة التي تضمّنتها.
Ask R8: Why are you keeping this?
إذا كان صف تتوقّع إزالته لا يزال في تطبيقك، يمكن أن يوضّح لك R8 السبب. ما عليك سوى إضافة هذه القاعدة:
# Asks R8 to explain why it's keeping a specific class class com.example.MyUnusedClass -whyareyoukeeping
أثناء عملية الإنشاء، ستعرض أداة R8 سلسلة المراجع الدقيقة التي أدّت إلى الاحتفاظ بهذه الفئة، ما يتيح لك تتبُّع المرجع وتعديل قواعدك.
للحصول على دليل كامل، يُرجى الاطّلاع على قسم تحديد المشاكل في R8 وحلّها.
الخطوات التالية
R8 هي أداة فعّالة لتحسين أداء تطبيقات Android، وتعتمد فعاليتها على فهم طريقة عملها بشكل صحيح كمحرّك للتحليل الثابت.
من خلال كتابة قواعد محدّدة على مستوى الأعضاء، والاستفادة من العناصر الرئيسية والتعليقات التوضيحية، واختيار خيارات الاحتفاظ المناسبة بعناية، يمكنك الاحتفاظ بما هو ضروري بالضبط. وأكثر الممارسات تقدّمًا هي إلغاء الحاجة إلى القواعد تمامًا من خلال اختيار مكتبات حديثة مستندة إلى إنشاء الرموز البرمجية بدلاً من المكتبات السابقة المستندة إلى الانعكاس.
أثناء متابعة "أسبوع تسليط الضوء على الأداء"، احرص على مشاهدة فيديو "أسبوع تسليط الضوء" اليوم على YouTube ومواصلة تحدّي R8. استخدِم العلامة #optimizationEnabled لطرح أي أسئلة حول تفعيل الأداة R8 أو تحديد المشاكل فيها وحلّها. نحن في الخدمة.
حان الوقت للاطّلاع على المزايا بنفسك.
ندعوك إلى تفعيل الوضع الكامل لأداة R8 في تطبيقك اليوم.
- اتّبِع أدلة المطوّرين للبدء: تفعيل تحسين التطبيق.
- تحقَّق مما إذا كنت لا تزال تستخدم
proguard-android.txtواستبدِله بـproguard-android-optimize.txt. - بعد ذلك، قِس التأثير، ولا تكتفِ بالشعور بالفرق، بل تأكَّد منه. قِس تحسُّن الأداء من خلال تعديل الرمز من تطبيق Macrobenchmark التجريبي على GitHub لقياس أوقات بدء التشغيل قبل وبعد التعديل.
نحن على ثقة بأنّك ستلاحظ تحسّنًا ملحوظًا في أداء تطبيقك.
يمكنك أيضًا استخدام الهاشتاغ #AskAndroid لطرح أسئلتك، وسيراقب خبراء Android أسئلتك ويجيبون عنها طوال الأسبوع.
ترقَّبوا مشاركتنا غدًا معلومات حول ميزة "التحسين المستند إلى الملف الشخصي" باستخدام "ملفات المرجع" و"ملفات بدء التشغيل"، وسنشارك أيضًا معلومات حول كيفية تحسُّن أداء العرض في Compose خلال الإصدارات السابقة، بالإضافة إلى اعتبارات الأداء المتعلقة بالعمل في الخلفية.
متابعة القراءة
-
أخبار المنتجات
يقدّم مؤتمر Google I/O كل عام إعلانات ومراجع جديدة في جميع الأنظمة المتكاملة والمنتجات، بما في ذلك تطوير تطبيقات Android. مع توجّه التطوير نحو الذكاء الاصطناعي والأدوات المستندة إلى وكيل، وسّعنا عروضنا لتقديم الدعم لك بشكل أفضل، بغض النظر عن الطريقة التي تختارها لتطوير تطبيقات Android.
Simona Milanovic • مدة القراءة: دقيقتان
-
أخبار المنتجات
في مؤتمر Google I/O لعام 2026، عرضنا كيف يمكن لأحدث التطورات في نظام Android المتكامل أن تساعدك في تحسين جودة تطبيقك إلى أقصى حدّ مع زيادة كفاءة التطوير.
Ataul Munim • مدة القراءة: 3 دقائق
-
أخبار المنتجات
في مؤتمر Google I/O 2026، أعلنّا عن تحوّل Android من نظام تشغيل إلى نظام ذكي، وأوضحنا كيف يمكنك إنشاء تجارب ذكية بشكلٍ مدمج مع النظام والاستفادة من إمكانات الذكاء الاصطناعي من Google في تطبيقاتك.
Jingyu Shi • مدة القراءة: دقيقتان
البقاء على اطّلاع على آخر التحديثات
يمكنك تلقّي أحدث الإحصاءات حول تطوير تطبيقات Android في بريدك الوارد أسبوعيًا.