R8 یک کامپایلر و ابزار بهینهسازی کد DEX است که فشردهسازی، desugaring و مبهمسازی برنامههای Android را در مرحله ساخت انجام میدهد. طبق دادههای Google Android Performance Team (2025)، استفاده از R8 اندازه APK را به طور متوسط 18٪ در مقایسه با ProGuard کاهش میدهد و زمان ساخت را 30٪ کوتاه میکند. از Android Gradle Plugin 8.0 به بعد، R8 کاملاً جایگزین ProGuard به عنوان ابزار استاندارد مبهمسازی شده است.
نکات اصلی
R8 یک برنامه پردازش و تبدیل بایتکد است که توسط Google به عنوان جایگزین ProGuard در اکوسیستم Android توسعه یافته است. برخلاف ProGuard که به عنوان یک ابزار جداگانه در مرحله فایلهای class کار میکند، R8 مستقیماً در کامپایلر DEX (D8/R8) یکپارچه شده است. این به R8 اجازه میدهد تحلیل و بهینهسازی را در سطح عمیقتری انجام دهد که برای ابزارهای خارجی قابل دسترس نیست.
R8 بایتکد Java را در قالب فایلهای class یا آرشیوهای JAR دریافت میکند و آن را در یک گذر به کد DEX بهینهشده تبدیل میکند. بهینهساز داخلی R8 بیش از 50 نوع مختلف تبدیل را انجام میدهد — از ساده (inline ثابتها) تا پیچیده (تحلیل دسترسیپذیری انواع با دقت تا یک فیلد خاص). طبق دادههای Google، معماری R8 به طور خاص برای کار در حالت چندنخی طراحی شده است که سرعت بالای ساخت را تضمین میکند.
R8 در Google I/O 2018 معرفی شد و اولین بار در Android Gradle Plugin 3.4 (2019) به عنوان جایگزین اختیاری ProGuard گنجانده شد. در AGP 7.0، R8 به ابزار پیشفرض برای همه پروژهها تبدیل شد و در AGP 8.0 (2023) پشتیبانی از ProGuard به طور کامل از پلاگین حذف شد. تا سال 2025، R8 تنها ابزار رسمی مبهمسازی و بهینهسازی برای Android است که توسط Google توصیه میشود.
R8 مجموعهای از قابلیتهای قدرتمند را در اختیار توسعهدهندگان قرار میدهد که از نظر کارایی بسیار فراتر از ProGuard هستند. بیایید مهمترین آنها را بررسی کنیم.
R8 تحلیل سراسری کد برنامه و تمام وابستگیهای آن را انجام میدهد و کلاسها و متدهای قابل دسترس را از طریق گراف فراخوانی از نقاط ورودی تعیین میکند. تحلیل R8 به دلیل دسترسی به نمایش کد DEX دقیقتر از ProGuard است. R8 میتواند نه تنها کل کلاسها و متدها، بلکه فیلدهای تکی را که هرگز استفاده نمیشوند حذف کند. طبق تستهای Google، R8 به طور متوسط 15٪ کد بیشتر نسبت به ProGuard در پروژههای مشابه حذف میکند.
Desugaring داخلی — یک قابلیت منحصربهفرد R8 است که در ProGuard وجود ندارد. R8 به طور خودکار عبارات lambda، ارجاع به متدها، اینترفیسهای با متدهای پیشفرض و try-with-resources Java 8+ را به کد سازگار با نسخههای قدیمی تبدیل میکند که در تمام سطوح API Android کار میکند. این کار توسعهدهنده را از نیاز به اضافهکردن کتابخانه جداگانه desugar_jdk_libs و پیکربندی دستی desugaring بینیاز میکند.
از آنجایی که R8 فرمت نهایی DEX را میبیند، میتواند بهینهسازیهایی انجام دهد که برای ProGuard غیرممکن است. R8 ثابتهای رشتهای یکسان را ادغام میکند، استثناهای استفاده نشده را حذف میکند، ساختارهای switch را بهینه میکند و inline تهاجمی با بازنویسی گراف فراخوانی انجام میدهد. این بهینهسازیها نه تنها اندازه APK را کاهش میدهند، بلکه عملکرد اجرای کد را در ART بهبود میبخشند.
// فعالسازی صریح R8 در build.gradle (اختیاری در AGP 8.0+)
android {
compileSdk 34
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'
), 'proguard-rules.pro'
}
}
}
// gradle.properties — فعالسازی اجباری R8
android.enableR8.fullMode=true
انتخاب بین R8 و ProGuard فقط برای پروژههایی که از AGP قدیمیتر از 8.0 استفاده میکنند مرتبط است. برای درک تفاوتهای معماری، مقایسه را بر اساس پارامترهای کلیدی بررسی میکنیم.
| پارامتر | R8 | ProGuard |
|---|---|---|
| یکپارچگی | داخلی در کامپایلر DEX | ابزار جداگانه |
| فشردهسازی کد | 15٪ مؤثرتر | سطح پایه |
| سرعت ساخت | 20-30٪ سریعتر | سرعت پایه |
| Desugaring | داخلی | پشتیبانی نمیشود |
| سازگاری قوانین | کامل با ProGuard | syntax استاندارد |
| پشتیبانی AGP 8.0+ | بله (استاندارد) | خیر (حذف شده) |
تست Google روی نمونهای از 100 برنامه محبوب Play Store نشان داد که R8 اندازه APK را به طور متوسط 18٪ در مقایسه با ProGuard کاهش میدهد. در برخی پروژهها با استفاده فعال از syntax Java 8+ و کتابخانههای شخص ثالث، تفاوت به 28٪ میرسید. برای برنامهای با اندازه 40 مگابایت، این به معنای صرفهجویی 5 تا 11 مگابایت است که برای کاربران با ترافیک محدود حیاتی است.
هر دو ابزار کد Kotlin را به درستی پردازش میکنند، اما R8 ساختارهای خاص Kotlin را بهتر بهینه میکند: lambdaها، توابع inline، کروتینها و انواع null-safe. R8 معنای metadataهای Kotlin را درک میکند و میتواند با خیال راحت بررسیهای null اضافی را حذف کرده و توابع inline را جاسازی کند. برای پروژههای Kotlin، R8 ابزار توصیهشده توسط Google است.
پیکربندی R8 به حداقل تغییرات در تنظیمات ساخت نیاز دارد، زیرا در AGP 8.0+ ابزار به طور پیشفرض استفاده میشود. بیایید جنبههای کلیدی پیکربندی را بررسی کنیم.
حالت کامل R8 (android.enableR8.fullMode=true) بهینهسازیهای تهاجمیتری را فعال میکند که کاهش اضافی 5-10٪ در اندازه APK ایجاد میکند. در این حالت، R8 تحلیل عمیقتری از کد انجام میدهد و کلاسها و متدهایی را که ProGuard قابل دسترس میدانست حذف میکند. حالت کامل ممکن است به قوانین -keep اضافی برای کتابخانههایی که از reflection استفاده میکنند نیاز داشته باشد.
# gradle.properties — فعالسازی حالت کامل R8
android.enableR8.fullMode=true
# قوانین اضافی برای full mode
-keep class com.example.reflection.** { *; }
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
در صورت بروز خطا در ساخت release با R8، Google توصیه میکند: فایل mapping را برای deobfuscation stacktrace بررسی کنید، به طور موقت fullMode را برای جداسازی مشکل غیرفعال کنید، -whyareyoukeeping را برای درک دلیل حذف نشدن کلاس اضافه کنید، و از پرچم --info Gradle برای دریافت log دقیق پردازش R8 استفاده کنید.
برای خودکارسازی ساخت با R8 در CI/CD، حفظ فایلهای mapping به عنوان مصنوعات ساخت مهم است. هر فایل mapping باید به شماره نسخه و نوع ساخت مرتبط باشد. Google بایگانی build/outputs/mapping/ را همراه با APK/AAB در سیستم مدیریت مصنوعات توصیه میکند. این کار امکان deobfuscation crashها را از هر نسخه از برنامه فراهم میکند.
تجربه چندین ساله استفاده از R8 در جامعه Android مجموعهای از روشهای اثباتشده را ایجاد کرده است که به جلوگیری از مشکلات معمول و به دست آوردن حداکثر سود از ابزار کمک میکند.
در هنگام انتقال از ProGuard به R8 توصیه میشود با AGP 7.x شروع کنید، جایی که R8 به طور پیشفرض فعال است اما fullMode غیرفعال است. پس از تأیید پایداری ساخت روی مجموعه کامل دستگاهها و سناریوها، میتوان fullMode را فعال کرد. هر مرحله نیاز به آزمایش ساخت release روی دستگاههای فیزیکی با نسخههای مختلف Android دارد.
فایلهای mapping R8 همان فرمت ProGuard را دارند اما به دلیل تحلیل دقیقتر حاوی اطلاعات بیشتری هستند. Google توصیه میکند: فایلهای mapping را به طور نامحدود نگهداری کنید — آنها برای deobfuscation crashهای نسخههای قدیمی مورد نیاز هستند. فایلهای mapping را از طریق بارگذاری خودکار با Firebase Crashlytics یکپارچه کنید. به طور منظم بررسی کنید که deobfuscation در کنسول Firebase به درستی نام کلاسها را بازیابی میکند.
حالت کامل R8 میتواند کدی را حذف کند که در حالت استاندارد قابل دسترس محسوب میشود. حوزههای حیاتی برای تست: صفحههای دارای WebView (R8 ممکن است کلاسهای اینترفیس bridge را حذف کند)، برنامههای دارای پلاگین از طریق classLoader، کتابخانههای analytics و crash reporting و viewهای سفارشی در فایلهای layout که با inflate ایجاد میشوند.
Google ردیابی اندازه APK را پس از اعمال R8 در هر ساخت توصیه میکند. از APK Analyzer در Android Studio برای مقایسه اندازه اجزای جداگانه استفاده کنید: classes.dex، resources.arsc و کتابخانههای کد بومی. R8 میتواند به طور غیرخطی بر اندازه فایلهای DEX تأثیر بگذارد — گاهی بهینهسازی تهاجمی به دلیل inline کردن منجر به افزایش اندازه میشود. نظارت منظم به شناسایی بهموقع ناهنجاریها و تصحیح قوانین مبهمسازی کمک میکند.
// نمونه کلاس حفظشده برای Firebase Crashlytics
@Keep
class CrashLogger {
fun logException(e: Throwable) {
FirebaseCrashlytics.getInstance().recordException(e)
}
}
// rules.pro — حفظ تمام کلاسهای دارای @Keep
// -keep @androidx.annotation.Keep class * { *; }
سوالات متداول
خیر، R8 در Android Gradle Plugin تعبیه شده است و با بهروزرسانی AGP به طور خودکار نصب میشود. از AGP 8.0 به بعد، ProGuard به طور کامل از پلاگین حذف شده است و R8 تنها ابزار است. برای AGP 7.x، R8 به طور پیشفرض استفاده میشود اما ProGuard به عنوان گزینه باقی میماند. نصب جداگانه R8 لازم نیست — کافی است نسخه AGP را بهروزرسانی کنید.
R8 به لطف سه عامل سریعتر است: یکپارچگی در کامپایلر DEX یک گذر اضافی روی بایتکد را حذف میکند، معماری چندنخی از پردازندههای چند هستهای مؤثرتر استفاده میکند، و تحلیل دسترسیپذیری هوشمندتر حجم کد پردازششده را کاهش میدهد. طبق تستهای Google روی یک پروژه متوسط، R8 پردازش را در 12 ثانیه انجام میدهد در مقابل 18 ثانیه برای ProGuard.
در AGP 7.x میتوان R8 را از طریق gradle.properties غیرفعال کرد: android.enableR8=false. در AGP 8.0+ بازگشت به ProGuard غیرممکن است زیرا پلاگین کاملاً به R8 منتقل شده است. اگر پروژه به طور حیاتی به رفتار خاص ProGuard وابسته است، توصیه میشود AGP را در نسخه 7.4 ثابت نگه دارید، جایی که هر دو ابزار در دسترس هستند.
R8 به لطف تحلیل داخلی metadataهای Kotlin، کروتینهای Kotlin را به درستی پردازش میکند. این ابزار معنای توابع suspend، اشیاء Continuation و تولید StateMachine توسط کامپایلر Kotlin را درک میکند. R8 کلاسهای ضروری کروتین را حذف نمیکند و میتواند در صورت ایمن بودن آنها را بهینه کند. برای پروژههای Kotlin، fullMode برای حداکثر بهینهسازی توصیه میشود.
رایجترین مشکلات هنگام مهاجرت: Missing classes — R8 کلاسهایی را حذف میکند که ProGuard نگه میداشت؛ Inlining issues — inline تهاجمی reflection را خراب میکند؛ Library incompatibility — کتابخانههایی با قوانین قدیمی ProGuard؛ Full mode crashes — حذف اضافی کد در fullMode. راهحل: روی دستگاههای فیزیکی تست کنید، از -keep برای reflection استفاده کنید و stacktrace را از طریق فایل mapping بررسی کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید