افزایه Android Gradle نسخه ۳.۶.۰ (فوریه ۲۰۲۰)

این نسخه از افزایه Android به موارد زیر نیاز دارد:

حداقل نسخه نسخه پیش‌فرض یادداشت‌ها
Gradle ‫۵.۶.۴ ‫۵.۶.۴ برای کسب اطلاعات بیشتر، به به‌روزرسانی Gradle مراجعه کنید.
ابزارهای ساخت SDK 28.0.3 28.0.3 نصب یا پیکربندی «ابزارهای ساخت کیت توسعه نرم‌افزار».

ویژگی‌های جدید

این نسخه از افزایه Android Gradle شامل ویژگی‌های جدید زیر است.

مشاهده صحافی

«اتصال نما» هنگام ارجاع به نماها در کدتان، ایمنی زمان ترجمه را فراهم می‌کند. اکنون می‌توانید findViewById() را با مرجع کلاس اتصال تولیدشده به‌طور خودکار جایگزین کنید. برای شروع استفاده از View binding، موارد زیر را در فایل build.gradle هر واحد اضافه کنید:

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

برای کسب اطلاعات بیشتر، سند View Binding را بخوانید.

پشتیبانی از افزونه Maven Publish

افزایه Android Gradle از افزایه Maven Publish Gradle پشتیبانی می‌کند که به شما امکان می‌دهد آرتیفکت‌های ساخت را در مخزن Apache Maven منتشر کنید. افزونه Android Gradle برای هر آرتیفکت تنوع ساخت در برنامه یا واحد کتابخانه شما یک مؤلفه ایجاد می‌کند که می‌توانید از آن برای سفارشی‌سازی انتشار در مخزن Maven استفاده کنید.

برای کسب اطلاعات بیشتر، به صفحه مربوط به نحوه استفاده از افزونه Maven Publish بروید.

ابزار بسته‌بندی پیش‌فرض جدید

هنگام ساختن نسخه اشکال‌زدایی برنامه‌تان، افزونه از ابزار بسته‌بندی جدیدی به‌نام zipflinger برای ساختن APK شما استفاده می‌کند. این ابزار جدید باید سرعت ساخت را بهبود بخشد. اگر ابزار بسته‌بندی جدید طبق انتظار شما کار نمی‌کند، لطفاً اشکال را گزارش کنید. می‌توانید با گنجاندن موارد زیر در فایل gradle.properties، به استفاده از ابزار بسته‌بندی قدیمی برگردید:

        android.useNewApkCreator=false
      

اسناد ساخت بومی

اکنون می‌توانید مدت زمانی را که Clang برای ساختن و پیوند دادن هر فایل C/C++‎ در پروژه‌تان نیاز دارد تعیین کنید. Gradle می‌تواند ردگیری Chrome را که حاوی مُهرهای زمان برای این رویدادهای کامپایلر است خروجی دهد تا بتوانید زمان موردنیاز برای ساخت پروژه‌تان را بهتر درک کنید. برای خروجی گرفتن از این فایل اِسناد ساخت، کارهای زیر را انجام دهید:

  1. هنگام اجرای ساخت Gradle، پرچم -Pandroid.enableProfileJson=true را اضافه کنید. برای مثال:

    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 با گزینه DSL useLegacyPackaging جایگزین شده است. برای اطلاعات بیشتر، یادداشت انتشار استفاده از DSL برای بسته‌بندی کتابخانه‌های بومی فشرده را ببینید.

نسخه NDK پیش‌فرض

اگر چند نسخه از NDK را بارگیری کنید، افزونه Android Gradle اکنون نسخه پیش‌فرضی را برای استفاده در کامپایل کردن فایل‌های کد منبع شما انتخاب می‌کند. قبلاً، افزونه جدیدترین نسخه بارگیری‌شده NDK را انتخاب می‌کرد. از ویژگی android.ndkVersion در فایل build.gradle واحد استفاده کنید تا پیش‌فرض انتخاب‌شده توسط افزونه را لغو کنید.

تولید کلاس R ساده‌شده

افزونه Android Gradle با تولید کردن فقط یک کلاس R برای هر واحد کتابخانه در پروژه شما و هم‌رسانی کردن آن کلاس‌های R با دیگر وابستگی‌های واحد، مسیر کلاس کامپایل را ساده می‌کند. این بهینه‌سازی باید به ساخت‌های سریع‌تر منجر شود، اما لازم است که موارد زیر را درنظر داشته باشید:

  • چون کامپایلر کلاس‌های R را با وابستگی‌های پیمانه بالادستی هم‌رسانی می‌کند، مهم است که هر پیمانه در پروژه‌تان از نام بسته منحصربه‌فردی استفاده کند.
  • رؤیت‌پذیری کلاس R کتابخانه برای سایر وابستگی‌های پروژه توسط پیکربندی مورداستفاده برای گنجاندن کتابخانه به‌عنوان وابستگی تعیین می‌شود. برای مثال، اگر «کتابخانه الف» شامل «کتابخانه ب» به‌عنوان وابستگی «رابط برنامه‌سازی کاربردی» باشد، «کتابخانه الف» و کتابخانه‌های دیگری که به «کتابخانه الف» وابسته هستند به کلاس R «کتابخانه ب» دسترسی دارند. بااین‌حال، کتابخانه‌های دیگر ممکن است به کلاس R کتابخانه B دسترسی نداشته باشند. اگر «کتابخانه الف» از پیکربندی وابستگی implementation استفاده کند. برای کسب اطلاعات بیشتر، درباره پیکربندی‌های وابستگی بخوانید.

برداشتن منابعی که در پیکربندی پیش‌فرض وجود ندارد

برای ماژول‌های «کتابخانه»، اگر منبعی را برای زبانی اضافه کنید که در مجموعه پیش‌فرض منابع اضافه نکرده‌اید (برای مثال، اگر hello_world را به‌عنوان منبع رشته در /values-es/strings.xml اضافه کنید اما آن منبع را در /values/strings.xml تعریف نکنید)، افزونه Android Gradle دیگر آن منبع را هنگام کامپایل کردن پروژه‌تان اضافه نمی‌کند. این تغییر رفتار باید منجر به استثناهای زمان اجرای Resource Not Found کمتر و بهبود سرعت ساخت شود.

D8 اکنون از خط‌مشی نگهداری CLASS برای حاشیه‌نویسی‌ها پیروی می‌کند

هنگام کامپایل کردن برنامه، D8 اکنون زمانی را که حاشیه‌نویسی‌ها خط‌مشی حفظ CLASS را اعمال می‌کنند رعایت می‌کند و آن حاشیه‌نویسی‌ها دیگر در زمان اجرا دردسترس نیستند. این رفتار هنگام تنظیم SDK هدف برنامه روی سطح میانای برنامه‌سازی کاربردی ۲۳ نیز وجود دارد، که قبلاً هنگام کامپایل کردن برنامه بااستفاده از نسخه‌های قدیمی‌تر افزونه Android Gradle و D8، دسترسی به این حاشیه‌نویسی‌ها را در زمان اجرا مجاز می‌کرد.

تغییرات رفتاری دیگر

  • aaptOptions.noCompress دیگر در هیچ پلاتفرمی به حروف بزرگ و کوچک حساس نیست (هم برای APK و هم برای بسته‌ها) و مسیرهایی را که از نویسه‌های بزرگ استفاده می‌کنند رعایت می‌کند.
  • ترابست داده‌ها اکنون به‌طور پیش‌فرض افزایشی است. برای اطلاعات بیشتر، مشکل شماره ۱۱۰۰۶۱۵۳۰ را ببینید.

  • اکنون همه آزمایش‌های واحد، ازجمله آزمایش‌های واحد Roboelectric، کاملاً قابل‌ذخیره در حافظه نهان هستند. برای اطلاعات بیشتر، مشکل شماره ۱۱۵۸۷۳۰۴۷ را ببینید.

رفع اشکال‌ها

این نسخه از افزایه Android Gradle شامل رفع اشکال‌های زیر است:

  • آزمایش‌های واحد Robolectric اکنون در ماژول‌های کتابخانه که از اتصال داده استفاده می‌کنند پشتیبانی می‌شود. برای اطلاعات بیشتر، مشکل شماره ۱۲۶۷۷۵۵۴۲ را ببینید.
  • اکنون می‌توانید تکالیف connectedAndroidTest را در چندین واحد اجرا کنید، درحالی‌که حالت اجرای موازی Gradle فعال است.

مشکلات شناخته‌شده

این بخش مشکلات شناخته‌شده‌ای را که در افزایه Android Gradle نسخه ۳.۶.۰ وجود دارد شرح می‌دهد.

عملکرد کند تکلیف Android Lint

به‌دلیل پس‌رفت در زیرساخت تجزیه Android Lint، تکمیل آن در برخی پروژه‌ها ممکن است بسیار بیشتر طول بکشد، که منجر به محاسبات کندتر انواع استنباط‌شده برای لامبداها در برخی ساختارهای کد می‌شود.

این مشکل به‌عنوان اشکالی در IDEA گزارش شده است و در «افزایه Android Gradle» نسخه ۴.۰ برطرف خواهد شد.

کلاس مانیفست ناموجود {:#agp-missing-manifest}

اگر برنامه‌تان اجازه‌های سفارشی را در مانیفست خود تعریف کند، افزایه Android Gradle معمولاً کلاس Manifest.java را تولید می‌کند که اجازه‌های سفارشی شما را به‌عنوان ثابت‌های رشته‌ای دربرمی‌گیرد. این افزونه این کلاس را با برنامه‌تان بسته‌بندی می‌کند تا بتوانید راحت‌تر به آن اجازه‌ها در زمان اجرا ارجاع دهید.

تولید کلاس مانیفست در افزایه Android Gradle نسخه ۳.۶.۰ خراب است. اگر برنامه‌تان را با این نسخه از افزونه بسازید و این نسخه به کلاس مانیفست ارجاع دهد، ممکن است استثنای 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";
                  }
                }