شخصی سازی کنید که کدام منابع را نگه دارید

وقتی بهینه‌سازی برنامه را فعال می‌کنید ، تنظیم isShrinkResources = true به بهینه‌ساز دستور می‌دهد منابعی را که استفاده نمی‌شوند حذف کند، که به کاهش اندازه برنامه شما کمک می‌کند. کوچک کردن منابع فقط در ارتباط با کوچک کردن کد کار می کند، بنابراین اگر منابع را بهینه می کنید، isMinifyEnabled = true نیز تنظیم کنید، برای مثال:

buildTypes {
    release {
        isMinifyEnabled = true
        isShrinkResources = true
        ...
    }
}

اگر می‌خواهید منابع خاصی را نگه دارید یا کنار بگذارید، یک فایل XML keep در منابع پروژه خود ایجاد کنید، برای مثال res/raw/my.package.keep.xml . فایل Keep دارای اجزای زیر است:

  • تگ <resources> - شامل تمام عناصر منبع فرزند و ویژگی‌های نگهداری/رد کردن است.
  • tools:keep خصیصه - لیستی از نام منابع جدا شده با کاما را می پذیرد که منابع را برای نگه داشتن مشخص می کند.
  • tools:discard خصیصه - لیستی از نام منابع جدا شده با کاما را می پذیرد که منابعی را برای دور انداختن مشخص می کند.

برای ارجاع چندین منبع در یک پوشه، از کاراکتر ستاره به عنوان علامت عام استفاده کنید، به عنوان مثال:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
    tools:discard="@layout/unused2" />

مشخص کردن منابعی که باید دور ریخته شوند ممکن است زمانی که می‌توانید آن‌ها را حذف کنید اضافی به نظر برسد، اما دور انداختن منابع می‌تواند هنگام استفاده از انواع ساخت مفید باشد.

انواع ساخت خاص را هدف قرار دهید

برای حذف منابع فقط در برخی از انواع ساخت، همه منابع خود را در فهرست پروژه مشترک قرار دهید، سپس یک فایل my.package.build.variant.keep.xml متفاوت برای هر نوع ساخت در فهرست منابع آن نوع ایجاد کنید. در فایل Keep، به صورت دستی منابعی را مشخص کنید تا زمانی که یک منبع داده شده در کد استفاده می شود (و در نتیجه توسط کوچک کننده حذف نمی شود) حذف شود، اما می دانید که در واقع برای نوع ساخت داده شده استفاده نخواهد شد.

منابع جایگزین استفاده نشده را حذف کنید

بهینه‌ساز فقط منابعی را حذف می‌کند که کد برنامه شما به آنها اشاره نمی‌کند، به این معنی که بهینه‌ساز منابع جایگزین را برای پیکربندی‌های مختلف دستگاه حذف نمی‌کند.

از ویژگی Android Gradle resConfigs در فایل build.gradle ماژول برنامه خود برای حذف فایل های منبع جایگزینی که برنامه شما به آن نیازی ندارد استفاده کنید.

برای مثال، اگر از کتابخانه‌ای استفاده می‌کنید که شامل منابع زبانی است (مانند خدمات Google Play)، برنامه شما شامل تمام رشته‌های زبان ترجمه‌شده برای پیام‌های موجود در آن کتابخانه‌ها می‌شود، چه بقیه برنامه شما به همان زبان‌ها ترجمه شده باشد یا نه. برای حفظ تنها زبان‌هایی که برنامه شما به طور رسمی از آنها پشتیبانی می‌کند، آن زبان‌ها را با استفاده از ویژگی resConfigs مشخص کنید. هر منبعی برای زبان های مشخص نشده حذف می شود.

قطعات زیر نشان می دهد که چگونه منابع زبان خود را فقط به انگلیسی و فرانسوی محدود کنید:

android {
    defaultConfig {
        ...
        resourceConfigurations.addAll(listOf("en", "fr"))
    }
}

یا

android {
    defaultConfig {
        ...
        resConfigs "en", "fr"
    }
}

وقتی برنامه‌ای را با استفاده از قالب Android App Bundle (AAB) منتشر می‌کنید، به‌طور پیش‌فرض تنها زبان‌های پیکربندی‌شده در دستگاه کاربر با نصب برنامه دانلود می‌شوند. به طور مشابه، فقط منابعی که با تراکم صفحه دستگاه و کتابخانه های بومی مطابق با ABI دستگاه مطابقت دارند در دانلود گنجانده شده است. برای اطلاعات بیشتر، دوباره فعال یا غیرفعال کردن انواع APKهای پیکربندی را ببینید.

برای برنامه‌های قدیمی که با APK منتشر می‌شوند (که قبل از آگوست ۲۰۲۱ ایجاد شده‌اند)، می‌توانید با ساختن چندین APK که پیکربندی‌های مختلف دستگاه را هدف قرار می‌دهند، چگالی صفحه یا منابع ABI را برای گنجاندن در APK خود سفارشی کنید.

هنگام ادغام منابع از درگیری اجتناب کنید

به‌طور پیش‌فرض، افزونه Android Gradle (AGP) منابعی با نام یکسان را ادغام می‌کند. این رفتار توسط ویژگی shrinkResources کنترل نمی‌شود و نمی‌توان آن را غیرفعال کرد زیرا این رفتار برای جلوگیری از خطا در زمانی که چندین منبع نامی را دارند که کد شما به آن ارجاع می‌دهد، ضروری است.

ادغام منابع تنها زمانی اتفاق می افتد که دو یا چند فایل نام، نوع و واجد شرایط منبع یکسانی را به اشتراک بگذارند. AGP فایلی را که شناسایی می کند به عنوان بهترین انتخاب از بین موارد تکراری انتخاب می کند (بر اساس ترتیب اولویت که در زیر توضیح داده شده است) و تنها آن یک منبع را برای توزیع در آرتیفکت ساخت نهایی به AAPT می دهد.

AGP به دنبال منابع تکراری در مکان‌های زیر می‌گردد:

  • منابع اصلی، مرتبط با مجموعه منبع اصلی، به طور کلی در src/main/res/ قرار دارند
  • پوشش های مختلف، از نوع ساخت و طعم های ساختمانی
  • وابستگی های پروژه کتابخانه

AGP منابع تکراری را به ترتیب اولویت آبشاری زیر ادغام می کند:

وابستگی ها → اصلی → طعم ساخت → نوع ساخت

به عنوان مثال، اگر یک منبع تکراری هم در منابع اصلی و هم در طعم ساخت ظاهر می شود، Gradle منبع را در طعم ساخت انتخاب می کند.

اگر منابع یکسان در مجموعه منبع یکسان ظاهر شوند، Gradle نمی تواند آنها را ادغام کند و یک خطای ادغام منابع منتشر می کند. اگر مجموعه‌های منبع متعددی را در ویژگی sourceSet فایل build.gradle ماژول خود تعریف کنید، می‌تواند اتفاق بیفتد، برای مثال، اگر هر دو src/main/res/ و src/main/res2/ دارای منابع یکسان باشند.

عیب یابی کاهش منابع

وقتی منابع را کوچک می کنید، پنجره Build خلاصه ای از منابع حذف شده از برنامه را نشان می دهد. (برای نمایش خروجی متن دقیق از Gradle روی Toggle view در سمت چپ پنجره کلیک کنید.) به عنوان مثال:

:android:shrinkDebugResources
Removed unused resources: Resource data reduced from 2570KB to 1711KB: Removed 33%
:android:validateDebugSigning

Gradle همچنین یک فایل تشخیصی به نام resources.txt در <module-name>/build/outputs/mapping/release/ (همان پوشه فایل های خروجی ProGuard) ایجاد می کند. این فایل شامل جزئیاتی از جمله اینکه کدام منابع به منابع دیگر ارجاع می دهند و کدام منابع استفاده شده یا حذف شده است.

برای مثال، برای اینکه بفهمید چرا @drawable/ic_plus_anim_016 هنوز در برنامه شما است، فایل resources.txt را باز کنید و نام فایل را جستجو کنید. ممکن است متوجه شوید که از منبع دیگری ارجاع داده شده است:

16:25:48.005 [QUIET] [system.out] @drawable/add_schedule_fab_icon_anim : reachable=true
16:25:48.009 [QUIET] [system.out] @drawable/ic_plus_anim_016

اکنون باید بدانید که چرا @drawable/add_schedule_fab_icon_anim قابل دسترسی است. و اگر به سمت بالا جستجو کنید، منبعی را خواهید یافت که در زیر عنوان فهرست شده است منابع قابل دسترسی ریشه عبارتند از: در resources.txt .

این بدان معناست که یک مرجع کد به add_schedule_fab_icon_anim وجود دارد، یعنی شناسه R.drawable آن در کد قابل دسترسی پیدا شده است.

مگر اینکه از بررسی دقیق استفاده کنید، شناسه‌های منبع را می‌توان به‌عنوان قابل دسترسی علامت‌گذاری کرد اگر ثابت‌های رشته‌ای وجود داشته باشند که به نظر می‌رسد ممکن است برای ساخت نام منابع برای منابع بارگذاری شده پویا استفاده شوند. در این صورت، اگر خروجی ساخت را برای نام منبع جستجو کنید، ممکن است پیامی مانند این پیدا کنید:

10:32:50.590 [QUIET] [system.out] Marking drawable:ic_plus_anim_016:2130837506
    used because its format-string matches string pool constant ic_plus_anim_%1$d.

اگر یکی از این رشته ها را می بینید و مطمئن هستید که از رشته برای بارگذاری پویا منبع داده شده استفاده نمی شود، از ویژگی tools:discard در فایل keep خود استفاده کنید تا به سیستم ساخت اطلاع دهید تا منبع را حذف کند.