اتّباع أفضل الممارسات

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

الأنماط الجيدة في قواعد الاحتفاظ بالبيانات

تكون قواعد الاحتفاظ بالبيانات المحدّدة جيدًا دقيقة قدر الإمكان:

  • بالنسبة إلى مواصفات الفئة، حدِّد دائمًا فئة معيّنة أو فئة أساسية أو فئة مزوّدة بتعليقات توضيحية إذا كان ذلك ممكنًا، كما هو موضّح في الأمثلة التالية:

    -keepclassmembers class com.example.MyClass {
      void someSpecificMethod();
    }
    
    -keepclassmembers ** extends com.example.MyBaseClass {
      void someSpecificMethod();
    }
    
    -keepclassmembers @com.example.MyAnnotation class ** {
      void someSpecificMethod();
    }
    
  • استخدِم التعليقات التوضيحية في رمز المصدر (مثل التعليق التوضيحي @Keep ) كلما أمكن ذلك، ثم استهدِف هذه التعليقات التوضيحية مباشرةً في قواعد الاحتفاظ. يؤدي ذلك إلى إنشاء رابط واضح وصريح بين الرمز والقواعد التي تحافظ عليه، ما يجعل عملية الإعداد أكثر قوة وأسهل للفهم وأقل عرضة لحدوث مشاكل عند تغيير الرمز.

    على سبيل المثال، تستخدم مكتبات مثل androidx.annotation النمط التالي:

    // In your source code
    @Keep
    class MyDataClass { /* ... */ }
    
    // In your R8 rules
    -keep @androidx.annotation.DisplayComponent class * {*;}
    

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

  • ويجب الإفصاح عن مواصفات العضو كلما أمكن ذلك، والإشارة فقط إلى أجزاء الفئة التي يجب الاحتفاظ بها لكي يعمل التطبيق. يُنصح بعدم تطبيق قاعدة على فئة بأكملها من خلال تحديد نطاق العضو الاختياري على أنّه { *; } إلا إذا كان ذلك ضروريًا.

    -keepclassmembers com.example.MyClass {
      void someSpecificMethod();
      void @com.example.MyAnnotation *;
    }
    
  • إذا كنت تستخدم الخيار العام repackageclasses، تجنَّب تحديد اسم الحزمة الاختياري. ويؤدي ذلك إلى إنشاء ملفات DEX أصغر حجمًا لأنّه يتم حذف بادئة الحزمة من أسماء الفئات التي تمت إعادة تجميعها.

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

-keepclassmembers class com.example.pkg.** { *; }

أمور يجب تجنّبها

تتضمّن بنية قاعدة الاحتفاظ بالبيانات العديد من الخيارات، ولكن لتحقيق فوائد مستدامة وقابلة للقياس في الأداء، ننصح بعدم استخدام ما يلي:

  • تجنَّب استخدام عامل النفي ! في قواعد الحفاظ على الفئات لأنّك قد تطبّق قاعدة عن غير قصد على كل فئة تقريبًا في تطبيقك.
  • لا تستخدِم قواعد الاحتفاظ على مستوى الحزمة، مثل -keep class com.example.pkg.** { *; } على المدى الطويل. ويمكن استخدامها مؤقتًا لتجنُّب المشاكل عند إعداد R8. لمزيد من المعلومات، يُرجى الاطّلاع على تحديد نطاق التحسين. بشكل عام، يجب توخّي الحذر عند استخدام أحرف البدل، والتأكّد من الاحتفاظ فقط بالرمز الذي تحتاج إليه.

إذا تعذّر عليك اتّباع هذه القواعد، من المحتمل أنّك تستخدم الكثير من عمليات الانعكاس المفتوحة، ويجب إما تجنُّب الانعكاس أو تجنُّب المكتبة باستخدام الانعكاس (راجِع دراسة حالة Gson).