الإصدار 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 مكوّن Publish Gradle Plugin لنظام Maven، ما يتيح لك نشر عناصر الإنشاء في مستودع 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.

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

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

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

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

في حال تنزيل إصدارات متعدّدة من حزمة NDK، سيختار الآن المكوّن الإضافي لنظام Gradle في Android إصدارًا تلقائيًا لاستخدامه في تجميع ملفات الرموز المصدر. في السابق، كان المكوّن الإضافي يختار أحدث إصدار تم تنزيله من حِزم 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";
                  }
                }