الإصدار 3.6.0 من "المكوّن الإضافي لنظام Gradle المتوافق مع Android" (فبراير 2020)

يتطلّب هذا الإصدار من المكوّن الإضافي لنظام Android ما يلي:

الحد الأدنى للإصدار الإصدار التلقائي الملاحظات
Gradle 5.6.4 5.6.4 لمزيد من المعلومات، يمكنك الاطّلاع على تحديث Gradle.
أدوات إنشاء حِزم SDK 28.0.3 28.0.3 ثبِّت أو اضبط أدوات إنشاء حِزم SDK.

الميزات الجديدة

يتضمّن هذا الإصدار من المكوّن الإضافي لنظام Gradle المتوافق مع Android الميزات الجديدة التالية:

ربط العرض

يضمن ربط العناصر أمان وقت الترجمة عند الإشارة إلى العناصر في الرمز البرمجي. يمكنك الآن استبدال findViewById() بمرجع فئة الربط المنشأة تلقائيًا. لبدء استخدام ربط العناصر المرئية، أدرِج ما يلي في ملف build.gradle لكل وحدة:

      android {
          viewBinding.enabled = true
      }
      
      android {
          viewBinding.enabled = true
      }
      

لمزيد من المعلومات، يُرجى الاطّلاع على مستندات ربط View.

إتاحة المكوّن الإضافي Maven Publish

يتضمّن المكوّن الإضافي لنظام Gradle المتوافق مع Android مكوّن Maven Publish Gradle الإضافي الذي يتيح لك نشر عناصر الإنشاء في مستودع Apache Maven. ينشئ المكوّن الإضافي لـ Android Gradle مكوّنًا لكل عنصر من عناصر الصيغة في تطبيقك أو وحدة مكتبتك، ويمكنك استخدامه لتخصيص نشر في مستودع Maven.

لمزيد من المعلومات، انتقِل إلى صفحة كيفية استخدام المكوّن الإضافي Maven Publish.

أداة الحزم التلقائية الجديدة

عند إنشاء إصدار تصحيح الأخطاء من تطبيقك، يستخدم المكوّن الإضافي أداة تغليف جديدة تُسمى zipflinger لإنشاء حزمة APK. من المفترض أن تؤدي هذه الأدوات الجديدة إلى تحسين سرعة إنشاء الإصدارات. إذا لم تعمل أداة الحزمة الجديدة على النحو المتوقّع، يُرجى الإبلاغ عن خطأ. يمكنك الرجوع إلى استخدام أداة الحزمة القديمة من خلال تضمين ما يلي في ملف gradle.properties:

        android.useNewApkCreator=false
      

تحديد مصدر الإصدار الأصلي

يمكنك الآن تحديد المدة التي يستغرقها Clang لإنشاء كل ملف C/C++ في مشروعك و الربط به. يمكن أن يُخرج Gradle تتبع Chrome الذي يحتوي على الطوابع الزمنية لأحداث المُجمِّع هذه حتى تتمكّن من معرفة الوقت المطلوب لإنشاء مشروعك بشكل أفضل. لإخراج ملف تحديد المصدر هذا، اتّبِع الخطوات التالية:

  1. أضِف العلامة -Pandroid.enableProfileJson=true عند تشغيل عملية إنشاء Gradle. مثلاً:

    gradlew assembleDebug -Pandroid.enableProfileJson=true

  2. افتح متصفّح Chrome واكتب chrome://tracing في شريط البحث.

  3. انقر على الزر تحميل وانتقِل إلى <var>project-root</var>/build/android-profile للعثور على الملف. اسم الملف هو profile-<var>timestamp</var>.json.gz.

يمكنك الاطّلاع على بيانات تحديد مصدر الإصدار المضمّن بالقرب من أعلى أداة العرض:

تتبُّع مصدر الإصدار الأصلي في Chrome

تغييرات السلوك

عند استخدام هذا الإصدار من المكوّن الإضافي، قد تلاحظ التغييرات التالية في السلوك.

المكتبات الأصلية المُجمَّعة غير المضغوطة تلقائيًا

عند إنشاء تطبيقك، يضبط المكوّن الإضافي الآن قيمة extractNativeLibs على "false" تلقائيًا. وهذا يعني أنّ المكتبات الأصلية تكون مُحسَّنة للصفحات ومُجمَّعة بدون ضغط. على الرغم من أنّ ذلك يؤدي إلى زيادة حجم التحميل، يستفيد المستخدمون من ما يلي:

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

إذا كنت تريد أن يحزِّم "مكوّن إضافي لـ Android Gradle" المكتبات المُجمَّعة من رموز برمجية أصلية بدلاً من ذلك، أدرِج ما يلي في ملف بيان تطبيقك:

        <application
          android:extractNativeLibs="true"
          ... >
        </application>
        
      

ملاحظة: تم استبدال سمة extractNativeLibs manifest بخيار useLegacyPackaging DSL. لمزيد من المعلومات، يُرجى الاطّلاع على ملاحظات الإصدار استخدام لغة وصف البيانات لحزم المكتبات المدمجة الأصلية.

إصدار NDK التلقائي

في حال تنزيل إصدارات متعدّدة من حزمة NDK، سيختار الآن المكوّن الإضافي لنظام Android Gradle إصدارًا تلقائيًا لاستخدامه في تجميع ملفات الرموز المصدر. في السابق، كان المكوّن الإضافي يختار أحدث إصدار تم تنزيله من حِزم NDK. استخدِم السمة android.ndkVersion في ملف build.gradle الخاص بالوحدة لتجاهل الإعداد التلقائي الذي اختاره المكوّن الإضافي.

إنشاء فئة R مبسّطة

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

  • بما أنّ المُجمِّع يشارك فئات R مع تبعيات الوحدات في المصدر المفتوح، من المهم أن تستخدم كل وحدة في مشروعك اسم حزمة فريدًا.
  • يتم تحديد مستوى وصول فئة R في المكتبة إلى العناصر الأخرى التي يعتمد عليها المشروع من خلال الإعدادات المستخدَمة لتضمين المكتبة كأحد عناصر الاعتماد. على سبيل المثال، إذا كانت المكتبة "أ" تتضمّن المكتبة "ب" كتبعية لـ "واجهة برمجة التطبيقات"، يمكن للمكتبة "أ" والمكتبات الأخرى التي تعتمد على المكتبة "أ" الوصول إلى فئة R في المكتبة "ب". ومع ذلك، قد لا تملك المكتبات الأخرى إذن الوصول إلى فئة R في المكتبة "ب". إذا كانت "المكتبة أ" تستخدم ملف الإعدادات المتعلّق بالتبعية implementation. للاطّلاع على مزيد من المعلومات، يمكنك الاطّلاع على إعدادات التبعيات.

إزالة الموارد غير المتوفّرة في الإعدادات التلقائية

بالنسبة إلى وحدات المكتبة، إذا أدرجت موردًا للغة لا تدرجها في المجموعة التلقائية من الموارد، على سبيل المثال، إذا أدرجت hello_world كمورد سلسلة في /values-es/strings.xml ولكنك لم تحدِّد هذا المورد في /values/strings.xml، لن يضمِّن المكوّن الإضافي لـ Android Gradle هذا المورد عند تجميع مشروعك. من المفترض أن يؤدي تغيير السلوك هذا إلى تقليل عدد Resource Not Found استثناءات وقت التشغيل وتحسين سرعة التصميم.

يراعي D8 الآن سياسة الاحتفاظ بالبيانات في CLASS للتعليقات التوضيحية.

عند تجميع تطبيقك، يراعي الإصدار D8 الآن الحالات التي تطبّق فيها التعليقات التوضيحية سياسة الاحتفاظ بـ CLASS ، ولا تعود هذه التعليقات التوضيحية متاحة عند التشغيل. ويظهر هذا السلوك أيضًا عند ضبط حزمة تطوير البرامج (SDK) المستهدفة للتطبيق على المستوى 23 لواجهة برمجة التطبيقات، والذي كان يسمح في السابق بالوصول إلى هذه التعليقات التوضيحية أثناء وقت التشغيل عند تجميع تطبيقك باستخدام الإصدارات القديمة من "مكوّن إضافي" Android Gradle وD8.

تغييرات السلوك الأخرى

  • لم يعُد aaptOptions.noCompress حسّاسًا لحالة الأحرف على جميع الأنظمة الأساسية (لكل من حِزم APK والحِزم) ويراعي المسارات التي تستخدم أحرفًا كبيرة.
  • أصبح ربط البيانات متزايدًا تلقائيًا. لمزيد من المعلومات، يُرجى الاطّلاع على المشكلة رقم 110061530.

  • يمكن الآن تخزين جميع اختبارات الوحدات، بما في ذلك اختبارات Roboelectric، بالكامل في ذاكرة التخزين المؤقت. لمزيد من المعلومات، يُرجى الاطّلاع على المشكلة رقم 115873047.

إصلاح الأخطاء

يتضمّن هذا الإصدار من المكوّن الإضافي لنظام Gradle المتوافق مع Android إصلاحات الأخطاء التالية:

  • أصبحت اختبارات Robolectric للوحدات متاحة الآن في وحدات المكتبة التي تستخدم عملية ربط البيانات. لمزيد من المعلومات، يُرجى الاطّلاع على المشكلة رقم 126775542.
  • يمكنك الآن تنفيذ مهام connectedAndroidTest على مستوى وحدات متعددة عندما يكون وضع التنفيذ المتزامن في Gradle مفعّلاً.

المشاكل المعروفة

يصف هذا القسم المشاكل المعروفة في المكوّن الإضافي لنظام Gradle المتوافق مع Android 3.6.0.

بطء أداء مهمة Android Lint

يمكن أن يستغرق إكمال عملية فحص Android Lint وقتًا أطول بكثير في بعض المشاريع بسبب تراجُع البنية الأساسية للتحليل، ما يؤدي إلى تباطؤ عملية احتساب الأنواع المستنتجة للوظائف اللامدا في بنى رموز معيّنة.

تم الإبلاغ عن المشكلة على أنّها خطأ في IDEA وسيتم حلّها في الإصدار 4.0 من المكوّن الإضافي لنظام Gradle المتوافق مع Android.

عدم توفّر فئة البيان {:#agp-missing-manifest}

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

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

  • يمكنك الإشارة إلى أذوناتك المخصّصة باسمها المحدَّد بالكامل. على سبيل المثال، "com.example.myapp.permission.DEADLY_ACTIVITY".

  • حدِّد الثوابت الخاصة بك كما هو موضّح أدناه:

                public final class CustomPermissions {
                  public static final class permission {
                    public static final String DEADLY_ACTIVITY="com.example.myapp.permission.DEADLY_ACTIVITY";
                  }
                }