کاربران اغلب از دانلود برنامههایی که خیلی حجیم به نظر میرسند، اجتناب میکنند، به خصوص در بازارهای نوظهور که دستگاهها به شبکههای 2G و 3G با سرعت پایین متصل میشوند یا با طرحهایی با محدودیت داده کار میکنند. این صفحه نحوه کاهش حجم دانلود برنامه شما را توضیح میدهد که به کاربران بیشتری امکان دانلود برنامه شما را میدهد.
برنامه خود را با بستههای برنامه اندروید آپلود کنید
برنامه خود را به عنوان یک بسته نرمافزاری اندروید (Android App Bundle) آپلود کنید تا هنگام انتشار در گوگل پلی، حجم برنامه بلافاصله کاهش یابد. بسته نرمافزاری اندروید (Android App Bundle) یک فرمت آپلود است که شامل تمام کدها و منابع کامپایل شده برنامه شما میشود، اما تولید APK و ثبت در گوگل پلی را به تعویق میاندازد.
مدل ارائه اپلیکیشن گوگل پلی سپس از بسته اپلیکیشن شما برای تولید و ارائه APK های بهینه شده برای پیکربندی دستگاه هر کاربر استفاده میکند، به طوری که آنها فقط کد و منابعی را که برای اجرای اپلیکیشن شما نیاز دارند دانلود میکنند. شما مجبور نیستید چندین APK را برای پشتیبانی از دستگاههای مختلف بسازید، امضا کنید و مدیریت کنید و کاربران دانلودهای کوچکتر و بهینهتری دریافت میکنند.
گوگل پلی محدودیت حجم دانلود فشرده ۲۰۰ مگابایت را برای برنامههای منتشر شده با بستههای برنامه اعمال میکند. حجمهای بزرگتر با استفاده از Play Feature Delivery و Play Asset Delivery امکانپذیر است، اما افزایش حجم برنامه شما میتواند بر موفقیت نصب تأثیر منفی بگذارد و تعداد حذف برنامهها را افزایش دهد، بنابراین توصیه میکنیم دستورالعملهای شرح داده شده در این صفحه را برای کاهش حجم دانلود برنامه خود تا حد امکان اعمال کنید.
ساختار APK را درک کنید
قبل از کاهش حجم برنامه، درک ساختار APK یک برنامه مفید است. یک فایل APK شامل یک آرشیو ZIP است که شامل تمام فایلهای تشکیلدهنده برنامه شما میشود. این فایلها شامل فایلهای کلاس جاوا، فایلهای منبع و فایلی حاوی منابع کامپایل شده هستند.
یک فایل APK شامل دایرکتوریهای زیر است:
-
META-INF/: شامل فایلهای امضایCERT.SFوCERT.RSAو همچنین فایل مانیفستMANIFEST.MFاست. -
assets/: شامل داراییهای برنامه است که برنامه میتواند با استفاده از یک شیءAssetManagerآنها را بازیابی کند. -
res/: شامل منابعی است که بهresources.arscکامپایل نشدهاند. -
lib/: شامل کد کامپایل شدهای است که مختص لایه نرمافزاری یک پردازنده است. این دایرکتوری شامل یک زیردایرکتوری برای هر نوع پلتفرم مانندarmeabi،armeabi-v7a،arm64-v8a،x86،x86_64وmipsاست.
یک APK همچنین شامل فایلهای زیر است. فقط AndroidManifest.xml اجباری است:
-
resources.arsc: شامل منابع کامپایل شده است. این فایل شامل محتوای XML از تمام پیکربندیهای پوشهres/values/است. ابزار بستهبندی این محتوای XML را استخراج میکند، آن را به صورت دودویی کامپایل میکند و محتوا را بایگانی میکند. این محتوا شامل رشتهها و سبکهای زبان و همچنین مسیرهایی به محتوایی است که مستقیماً در فایلresources.arscوجود ندارد، مانند فایلهای طرحبندی و تصاویر. -
classes.dex: شامل کلاسهای کامپایل شده در قالب فایل DEX است که توسط ماشین مجازی Dalvik یا ART قابل درک است. -
AndroidManifest.xml: شامل فایل مانیفست اصلی اندروید است. این فایل شامل نام، نسخه، حقوق دسترسی و فایلهای کتابخانهای ارجاعشدهی برنامه است. این فایل از فرمت XML باینری اندروید استفاده میکند.
کاهش تعداد و اندازه منابع
اندازه APK شما بر سرعت بارگذاری برنامه، میزان حافظه مورد استفاده و میزان مصرف برق آن تأثیر میگذارد. شما میتوانید با کاهش تعداد و اندازه منابع موجود در APK، آن را کوچکتر کنید. به طور خاص، میتوانید منابعی را که برنامه شما دیگر از آنها استفاده نمیکند حذف کنید و میتوانید به جای فایلهای تصویری از اشیاء Drawable مقیاسپذیر استفاده کنید. در این بخش، این روشها و سایر روشهایی که میتوانید منابع برنامه خود را کاهش دهید تا اندازه کلی APK شما کاهش یابد، مورد بحث قرار میگیرد.
منابع بلااستفاده را حذف کنید
ابزار lint - یک تحلیلگر کد استاتیک که در اندروید استودیو موجود است - منابعی را در پوشه res/ شما شناسایی میکند که کد شما به آنها ارجاع نمیدهد. وقتی ابزار lint یک منبع بالقوه بلااستفاده را در پروژه شما کشف میکند، پیامی مانند مثال زیر چاپ میکند:
res/layout/preferences.xml: Warning: The resource R.layout.preferences appears
to be unused [UnusedResources]
کتابخانههایی که به کد خود اضافه میکنید ممکن است شامل منابع استفاده نشده باشند. اگر shrinkResources در فایل build.gradle.kts برنامه خود فعال کنید، Gradle میتواند به طور خودکار منابع را از طرف شما حذف کند.
کاتلین
android { // Other settings. buildTypes { getByName("release") { minifyEnabled = true shrinkResources = true proguardFiles(getDefaultProguardFile('proguard-android.txt'), "proguard-rules.pro") } } }
گرووی
android { // Other settings. buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
برای استفاده از shrinkResources ، قابلیت کاهش کد (code shrinking) را فعال کنید. در طول فرآیند ساخت، R8 ابتدا کد استفاده نشده را حذف میکند. سپس، افزونه Android Gradle منابع استفاده نشده را حذف میکند.
برای اطلاعات بیشتر در مورد کاهش کد و منابع، و سایر روشهای کاهش حجم APK توسط اندروید استودیو، به بخش «کاهش، مبهمسازی و بهینهسازی برنامه» مراجعه کنید.
در افزونه اندروید Gradle نسخه ۷.۰ و بالاتر، میتوانید پیکربندیهایی را که برنامه شما پشتیبانی میکند، تعریف کنید. Gradle این اطلاعات را با استفاده از resourceConfigurations و گزینه defaultConfig به سیستم ساخت (build system) منتقل میکند. سپس سیستم ساخت از نمایش منابع سایر پیکربندیهای پشتیبانی نشده در APK جلوگیری میکند و اندازه APK را کاهش میدهد. برای اطلاعات بیشتر در مورد این ویژگی، به حذف منابع جایگزین استفاده نشده مراجعه کنید.
استفاده از منابع کتابخانهها را به حداقل برسانید
وقتی یک برنامه اندروید توسعه میدهید، معمولاً از کتابخانههای خارجی برای بهبود کاربرد و تطبیقپذیری برنامه خود استفاده میکنید. به عنوان مثال، ممکن است برای بهبود تجربه کاربری در دستگاههای قدیمیتر به AndroidX مراجعه کنید، یا میتوانید از سرویسهای Google Play برای بازیابی ترجمههای خودکار برای متن درون برنامه خود استفاده کنید.
اگر یک کتابخانه برای سرور یا دسکتاپ طراحی شده باشد، میتواند شامل اشیاء و متدهای زیادی باشد که برنامه شما به آنها نیاز ندارد. برای اینکه فقط بخشهایی از کتابخانه که برنامه شما به آنها نیاز دارد را در آن بگنجانید، میتوانید فایلهای کتابخانه را ویرایش کنید، البته اگر مجوز به شما اجازه تغییر کتابخانه را بدهد. همچنین میتوانید از یک کتابخانه جایگزین و سازگار با موبایل برای افزودن قابلیتهای خاص به برنامه خود استفاده کنید.
رمزگشایی تصویر متحرک بومی
در اندروید ۱۲ (API سطح ۳۱)، API مربوط به NDK ImageDecoder گسترش یافته تا تمام فریمها و دادههای زمانبندی را از تصاویری که از فرمتهای فایل GIF متحرک و WebP متحرک استفاده میکنند، رمزگشایی کند.
برای کاهش بیشتر حجم APK و بهرهمندی از بهروزرسانیهای آینده مربوط به امنیت و عملکرد، از ImageDecoder به جای کتابخانههای شخص ثالث استفاده کنید.
برای جزئیات بیشتر در مورد API ImageDecoder ، به API reference و نمونه موجود در GitHub مراجعه کنید.
فقط از چگالیهای خاص پشتیبانی میکند
اندروید از تراکم صفحه نمایشهای مختلفی پشتیبانی میکند، مانند موارد زیر:
-
ldpi -
mdpi -
tvdpi -
hdpi -
xhdpi -
xxhdpi -
xxxhdpi
اگرچه اندروید از تراکمهای قبلی پشتیبانی میکند، اما نیازی نیست که فایلهای رستری شده خود را به هر تراکمی اکسپورت کنید.
اگر میدانید که تنها درصد کمی از کاربران شما دستگاههایی با تراکم صفحه نمایش خاص دارند، در نظر بگیرید که آیا نیاز دارید آن تراکمها را در برنامه خود بگنجانید یا خیر. اگر منابعی را برای تراکم صفحه نمایش خاصی در نظر نگیرید، اندروید به طور خودکار منابع موجود را که در ابتدا برای تراکم صفحه نمایشهای دیگر طراحی شدهاند، مقیاسبندی میکند.
اگر برنامه شما فقط به تصاویر مقیاسپذیر نیاز دارد، میتوانید با داشتن یک نوع واحد از یک تصویر در drawable-nodpi/ فضای بیشتری را ذخیره کنید. توصیه میکنیم حداقل یک نوع تصویر xxhdpi را در برنامه خود قرار دهید.
برای اطلاعات بیشتر در مورد تراکم صفحه نمایش، به اندازهها و تراکمهای صفحه نمایش مراجعه کنید.
استفاده از اشیاء قابل ترسیم
برخی از تصاویر به منبع تصویر ثابت نیاز ندارند. این چارچوب میتواند به جای آن، تصویر را به صورت پویا در زمان اجرا ترسیم کند. اشیاء Drawable - یا <shape> در XML - میتوانند فضای بسیار کمی را در APK شما اشغال کنند. علاوه بر این، اشیاء Drawable XML تصاویر تک رنگ مطابق با دستورالعملهای طراحی متریال تولید میکنند.
استفاده مجدد از منابع
شما میتوانید برای انواع مختلف یک تصویر، مانند نسخههای رنگی، سایهدار یا چرخانده شده از همان تصویر، یک منبع جداگانه در نظر بگیرید. با این حال، توصیه میکنیم که از همان مجموعه منابع دوباره استفاده کنید و آنها را در زمان اجرا در صورت نیاز سفارشی کنید.
اندروید چندین ابزار برای تغییر رنگ یک عنصر ارائه میدهد، چه با استفاده از ویژگیهای android:tint و tintMode .
همچنین میتوانید منابعی را که فقط معادل چرخیده منبع دیگری هستند، حذف کنید. قطعه کد زیر مثالی از تبدیل «انگشت شست به بالا» به «انگشت شست به پایین» با چرخاندن تصویر در وسط و چرخاندن ۱۸۰ درجه آن ارائه میدهد:
<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_thumb_up" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="180" />
رندر از کد
همچنین میتوانید با رندر کردن تصاویر به صورت رویهای، حجم APK خود را کاهش دهید. رندر کردن رویهای باعث آزاد شدن فضا میشود زیرا دیگر فایل تصویری را در APK خود ذخیره نمیکنید.
فایلهای PNG کرانچ
ابزار aapt میتواند منابع تصویری که در res/drawable/ قرار دارند را با فشردهسازی بدون اتلاف در طول فرآیند ساخت بهینهسازی کند. برای مثال، ابزار aapt میتواند یک PNG با رنگ واقعی که به بیش از ۲۵۶ رنگ نیاز ندارد را به یک PNG با ۸ بیت و یک پالت رنگ تبدیل کند. انجام این کار منجر به تصویری با کیفیت برابر اما با حجم حافظه کمتر میشود.
aapt محدودیتهای زیر را دارد:
- ابزار
aaptفایلهای PNG موجود در پوشهasset/را فشرده نمیکند. - فایلهای تصویری باید از ۲۵۶ رنگ یا کمتر استفاده کنند تا ابزار
aaptبتواند آنها را بهینه کند. - ابزار
aaptممکن است فایلهای PNG که از قبل فشرده شدهاند را حجیمتر کند. برای جلوگیری از این امر، میتوانید از پرچمisCrunchPngsبرای غیرفعال کردن این فرآیند برای فایلهای PNG استفاده کنید:
کاتلین
buildTypes.all { isCrunchPngs = false }
گرووی
buildTypes.all { isCrunchPngs = false }
فشردهسازی فایلهای PNG و JPEG
شما میتوانید با استفاده از ابزارهایی مانند pngcrush ، pngquant یا zopflipng ، اندازه فایلهای PNG را بدون از دست دادن کیفیت تصویر کاهش دهید. همه این ابزارها میتوانند ضمن حفظ کیفیت تصویر، اندازه فایل PNG را کاهش دهند.
ابزار pngcrush به طور خاص مؤثر است. این ابزار فیلترهای PNG و پارامترهای zlib (Deflate) را تکرار میکند و از هر ترکیبی از فیلترها و پارامترها برای فشردهسازی تصویر استفاده میکند. سپس پیکربندیای را انتخاب میکند که کوچکترین خروجی فشردهشده را ارائه میدهد.
برای فشردهسازی فایلهای JPEG، میتوانید از ابزارهایی مانند packJPG و guetzli استفاده کنید.
استفاده از فرمت فایل WebP
به جای استفاده از فایلهای PNG یا JPEG، میتوانید از فرمت فایل WebP برای تصاویر خود استفاده کنید. فرمت WebP مانند JPG و PNG، فشردهسازی با اتلاف و شفافیت را فراهم میکند و میتواند فشردهسازی بهتری نسبت به JPEG یا PNG ارائه دهد.
شما میتوانید تصاویر BMP، JPG، PNG یا تصاویر ثابت GIF موجود را با استفاده از اندروید استودیو به فرمت WebP تبدیل کنید. برای اطلاعات بیشتر، به ایجاد تصاویر WebP مراجعه کنید.
استفاده از گرافیک برداری
شما میتوانید از گرافیکهای برداری برای ایجاد آیکونهای مستقل از وضوح و سایر رسانههای مقیاسپذیر استفاده کنید. میتوانید از این گرافیکها برای کاهش چشمگیر ردپای APK خود استفاده کنید. تصاویر برداری در اندروید به صورت اشیاء VectorDrawable نمایش داده میشوند. با یک شیء VectorDrawable ، یک فایل ۱۰۰ بایتی میتواند تصویری واضح به اندازه صفحه نمایش ایجاد کند.
با این حال، زمان بسیار بیشتری طول میکشد تا سیستم هر شیء VectorDrawable را رندر کند، و تصاویر بزرگتر حتی بیشتر طول میکشد تا روی صفحه نمایش داده شوند. بنابراین، فقط هنگام نمایش تصاویر کوچک، از این گرافیکهای برداری استفاده کنید.
برای اطلاعات بیشتر در مورد کار با اشیاء VectorDrawable ، به Drawables مراجعه کنید.
استفاده از گرافیک برداری برای تصاویر متحرک
از AnimationDrawable برای ایجاد انیمیشنهای فریم به فریم استفاده نکنید، زیرا انجام این کار مستلزم آن است که برای هر فریم از انیمیشن، یک فایل بیتمپ جداگانه قرار دهید که این امر حجم APK شما را به شدت افزایش میدهد.
در عوض، از AnimatedVectorDrawableCompat برای ایجاد فایلهای برداری متحرک استفاده کنید.
کاهش کد بومی و جاوا
شما میتوانید از روشهای زیر برای کاهش حجم کدهای جاوا و native در برنامه خود استفاده کنید.
حذف کدهای تولید شده غیرضروری
مطمئن شوید که ردپای هر کدی که به طور خودکار تولید میشود را درک میکنید. به عنوان مثال، بسیاری از ابزارهای بافر پروتکل تعداد زیادی متد و کلاس تولید میکنند که میتواند حجم برنامه شما را دو یا سه برابر کند.
از شمارشها اجتناب کنید
یک enum میتواند حدود ۱.۰ تا ۱.۴ کیلوبایت به فایل classes.dex برنامه شما اضافه کند. این اضافات میتوانند به سرعت برای سیستمهای پیچیده یا کتابخانههای مشترک انباشته شوند. در صورت امکان، استفاده از حاشیهنویسی @IntDef و کوچکسازی کد را برای حذف enumها و تبدیل آنها به اعداد صحیح در نظر بگیرید. این تبدیل نوع، تمام مزایای ایمنی نوع enumها را حفظ میکند.
کاهش اندازه فایلهای باینری بومی
اگر برنامه شما از کد بومی و Android NDK استفاده میکند، میتوانید با بهینهسازی کد، اندازه نسخه انتشار برنامه خود را نیز کاهش دهید. دو تکنیک مفید، حذف نمادهای اشکالزدایی و عدم استخراج کتابخانههای بومی است.
نمادهای اشکالزدایی را حذف کنید
استفاده از نمادهای اشکالزدایی در صورتی منطقی است که برنامه شما در حال توسعه باشد و هنوز نیاز به اشکالزدایی داشته باشد. از ابزار arm-eabi-strip که در Android NDK ارائه شده است برای حذف نمادهای اشکالزدایی غیرضروری از کتابخانههای بومی استفاده کنید. پس از آن، میتوانید نسخه آزمایشی خود را کامپایل کنید.
از استخراج کتابخانههای بومی خودداری کنید
هنگام ساخت نسخه آزمایشی برنامه خود، فایلهای .so غیرفشرده را در APK با تنظیم useLegacyPackaging روی false در فایل build.gradle.kts برنامه خود، بستهبندی کنید. غیرفعال کردن این پرچم مانع از کپی کردن فایلهای .so PackageManager از APK به سیستم فایل در حین نصب میشود. این روش باعث میشود بهروزرسانیهای برنامه شما کوچکتر شوند.
چندین APK کمحجم را نگهداری کنید
APK شما ممکن است حاوی محتوایی باشد که کاربران دانلود میکنند اما هرگز از آن استفاده نمیکنند، مانند زبانهای اضافی یا منابع با تراکم صفحه نمایش. برای اطمینان از حداقل دانلود برای کاربران، برنامه خود را با استفاده از Android App Bundles در Google Play آپلود کنید. آپلود بستههای برنامه به Google Play اجازه میدهد تا APKهای بهینه شده را برای پیکربندی دستگاه هر کاربر تولید و ارائه دهد، به طوری که آنها فقط کد و منابعی را که برای اجرای برنامه شما نیاز دارند دانلود کنند. شما مجبور نیستید چندین APK را برای پشتیبانی از دستگاههای مختلف بسازید، امضا کنید و مدیریت کنید و کاربران دانلودهای کوچکتر و بهینهتری دریافت میکنند.
اگر برنامه خود را در گوگل پلی منتشر نمیکنید، میتوانید برنامه خود را به چندین APK تقسیم کنید که بر اساس عواملی مانند اندازه صفحه نمایش یا پشتیبانی از بافت GPU از هم متمایز میشوند.
وقتی کاربری برنامه شما را دانلود میکند، دستگاه او بر اساس ویژگیها و تنظیمات دستگاه، APK صحیح را دریافت میکند. به این ترتیب، دستگاهها برای ویژگیهایی که ندارند، دارایی دریافت نمیکنند. به عنوان مثال، اگر کاربری دستگاه hdpi داشته باشد، به منابع xxxhdpi که ممکن است برای دستگاههایی با نمایشگرهای با تراکم بالاتر در نظر بگیرید، نیازی ندارد.
برای اطلاعات بیشتر، به ساخت چندین APK و پشتیبانی از چندین APK مراجعه کنید.