ProGuard — ابزاری برای فشردهسازی، بهینهسازی و مبهمسازی بایتکد Java است که در Android SDK برای محافظت از برنامهها در برابر reverse-engineering ادغام شده است. طبق Google I/O Security Session (2025)، پیکربندی صحیح ProGuard اندازه APK را 15-25٪ کاهش میدهد و خطر نشت کد را 60٪ پایین میآورد. این ابزار به استانداردی برای توسعه Android تبدیل شده و در میلیونها برنامه در سراسر جهان استفاده میشود.
نکات اصلی
ProGuard — ابزاری با توزیع آزاد برای پردازش بایتکد Java است که توسط شرکت Guardsquare توسعه یافته است. این ابزار در Android SDK تعبیه شده و سه عملکرد کلیدی را انجام میدهد: فشردهسازی (shrinking)، بهینهسازی (optimization) و مبهمسازی (obfuscation) کد. ProGuard کل بایتکد برنامه و وابستگیهای آن را تحلیل میکند، کلاسها و متدهای استفادهنشده را شناسایی کرده، آنها را حذف میکند و سپس کد باقیمانده را پنهان میسازد.
ProGuard توسط اریک لافورژ در سال 2000 به عنوان ابزاری برای بهینهسازی برنامههای Java ایجاد شد. با ظهور Android در سال 2008، ProGuard در Android SDK ادغام شد و به ابزاری استاندارد برای محافظت از برنامهها تبدیل گردید. طبق آمار Guardsquare (2024)، ProGuard در بیش از 80٪ برنامههای Google Play از جمله برنامههای بزرگترین بانکها و شرکتهای فناوری استفاده میشود.
ProGuard پردازش را در چهار مرحله انجام میدهد. در مرحله اول (shrink) ابزار نقاط ورودی برنامه را تحلیل کرده و مشخص میکند که کدام کلاسها، متدها و فیلدها در طول اجرا قابل دسترسی هستند. در مرحله دوم (optimize) ProGuard بایتکد را برای افزایش کارایی تبدیل میکند. مرحله سوم (obfuscate) شناسهها را تغییر نام میدهد. در مرحله نهایی preverify ابردادههای لازم برای تأیید بایتکد در ماشین مجازی را اضافه میکند.
بیایید هر یک از سه عملکرد اصلی ProGuard را به تفصیل بررسی کنیم: فشردهسازی، بهینهسازی و مبهمسازی. درک هر مکانیزم به پیکربندی بهینه ابزار کمک میکند.
ProGuard گراف فراخوانی را از نقاط ورودی (متد main، Activity، BroadcastReceiver) تحلیل کرده و کد استفادهنشده را حذف میکند. در یک پروژه معمولی Android با کتابخانههایی مانند Retrofit، OkHttp و Gson، فشردهسازی میتواند تا 40٪ از بایتکد را حذف کند، از جمله متدهای استفادهنشده کتابخانهها، کد debug و کلاسهای تست. این کار مستقیماً اندازه APK را کاهش داده و زمان بارگذاری برنامه را کوتاه میکند.
در مرحله بهینهسازی، ProGuard بیش از 20 تبدیل مختلف بایتکد را انجام میدهد: درونخطیسازی متدهای کوتاه، حذف پارامترهای استفادهنشده، سادهسازی عبارات منطقی، ادغام بلوکهای کد یکسان. به عنوان مثال، getter و setterهای کوتاه میتوانند با دسترسی مستقیم به فیلد جایگزین شوند. بهینهسازی میتواند اجرای کد را بسته به ساختار برنامه 5-15٪ سریعتر کند.
مبهمسازی در ProGuard با تغییر نام کلاسها، متدها و فیلدها به دنبالههای کوتاه از کاراکترها کار میکند: a، b، c، a.a، a.b و غیره. تمام ارجاعات به عناصر تغییر نامیافته به طور خودکار در سراسر کد بهروزرسانی میشوند. توجه به این نکته مهم است که مبهمسازی رفتار برنامه را تغییر نمیدهد، بلکه فقط درک کد decompile شده را دشوار میکند. کتابخانهها و APIهای عمومی باید از طریق قوانین keep از مبهمسازی مستثنی شوند.
// قبل از مبهمسازی ProGuard
public class LoginManager {
public User authenticateUser(String username, String password) {
// منطق احراز هویت
}
}
// بعد از مبهمسازی ProGuard
public class a {
public Object a(String b, String c) {
// همان منطق با شناسههای تغییر نام یافته
}
}
پیکربندی ProGuard — مرحله بحرانی تنظیم ساخت برنامه Android است. قوانین نادرست میتوانند منجر به حذف کلاسهای ضروری و در نتیجه crash در نسخه release شوند.
فعالسازی ProGuard در پروژه Android شامل تنظیم پرچم minifyEnabled بر روی true برای نوع ساخت release است. قوانین استاندارد ProGuard همراه با Android SDK در فایل proguard-android-optimize.txt ارائه میشوند. قوانین سفارشی در یک فایل جداگانه proguard-rules.pro اضافه میشوند. هنگام ساخت، ProGuard ابتدا قوانین استاندارد و سپس قوانین سفارشی را اعمال میکند که امکان بازنویسی پیکربندی پایه را فراهم میکند.
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'
), 'proguard-rules.pro'
}
}
}
فایل سفارشی قوانین شامل دستورالعملهای خاص برای یک پروژه معین است. قوانین معمول شامل حفظ کلاسهای استفاده شده از طریق reflection، مدلهای داده برای سریالسازی Gson/Moshi، رابطهای callback کتابخانهها و کلاسهای دارای حاشیهنویسی خاص است. هر دستورالعمل با کلمه کلیدی -keep، -dontwarn یا -keepclassmembers شروع میشود و الگوی کلاسی را مشخص میکند که ProGuard نباید آن را تغییر دهد.
# حفظ مدلهای داده برای Gson
-keep class com.example.data.model.** { *; }
# حفظ کلاسهای استفاده شده از طریق reflection
-keep class * implements com.google.gson.TypeAdapterFactory
# نادیده گرفتن هشدارهای کتابخانه
-dontwarn okhttp3.internal.**
-dontwarn retrofit2.**
# حفظ enumها (ویژگی ProGuard)
-keep class * extends java.lang.Enum { *; }
دستور زبان پیکربندی ProGuard شامل چندین دسته از دستورالعملها است که هر یک جنبه خاصی از پردازش را کنترل میکند. بیایید موارد اصلی لازم برای پیکربندی صحیح را بررسی کنیم.
| دستورالعمل | هدف | مثال |
|---|---|---|
| -keep | حفظ کامل کلاس و اعضای آن | -keep class com.example.MyClass |
| -keepclassmembers | حفظ فقط اعضای کلاس | -keepclassmembers class * { @Inject *; } |
| -dontwarn | نادیده گرفتن هشدارها | -dontwarn okhttp3.internal.** |
| -keepparameternames | حفظ نام پارامترهای متد | -keepparameternames |
| -keepattributes | حفظ ویژگیها (حاشیهنویسیها، EnclosingMethod) | -keepattributes *Annotation* |
| -dontoptimize | غیرفعال کردن بهینهسازی | -dontoptimize |
ProGuard نمیتواند کدی را که از طریق reflection (Class.forName())، ServiceLoader یا بارگذاری پویای فایلهای DEX بارگذاری میشود، به صورت ایستا تحلیل کند. اگر یک کلاس با نام رشتهای ایجاد شود، ProGuard از وجود آن بیخبر است و ممکن است آن را به عنوان استفادهنشده حذف کند. همه این کلاسها باید صریحاً از طریق -keep حفظ شوند. این رایجترین دلیل crashها در نسخههای release پس از فعالسازی ProGuard است.
کتابخانهها اغلب شامل قوانین ProGuard خاص خود هستند که به طور خودکار از طریق consumer-rules.pro تعبیه شده در فایل AAR به ساخت اضافه میشوند. Android Gradle Plugin به طور خودکار این قوانین را هنگام ساخت اعمال میکند. توسعهدهنده فقط باید اطمینان حاصل کند که تمام کتابخانههای استفاده شده قوانین صحیحی ارائه میدهند و در صورت نیاز آنها را در پروژه تکمیل کند.
در صورت بروز خطا پس از فعالسازی ProGuard، از فایل mapping برای deobfuscation stack trace استفاده کنید. برای تشخیص، از کلید -whyareyoukeeping استفاده میشود که دلیل حفظ کلاس را در خروجی ساخت نشان میدهد. غیرفعال کردن موقت -optimizationpasses و -obfuscation امکان مکانیابی مشکل را فراهم میکند. طبق Guardsquare، 80٪ مشکلات ProGuard با افزودن قوانین -keep برای کلاسهای reflection حل میشود.
با انتشار Android Gradle Plugin 3.4 (2019)، گوگل R8 — جانشین ProGuard را معرفی کرد که مستقیماً در کامپایلر D8/R8 ادغام شده است. تا سال 2023، R8 کاملاً جایگزین ProGuard در AGP 8.0 شد، اما درک تفاوتهای معماری برای مهاجرت پروژهها مهم است.
ProGuard به عنوان یک ابزار جداگانه عمل میکند که بایتکد Java (فایلهای .class) را قبل از تبدیل به DEX پردازش میکند. R8 در کامپایلر DEX ادغام شده و کد را در سطح پایینتری پردازش میکند که امکان انجام بهینهسازیهایی را فراهم میکند که در ProGuard در دسترس نیست. R8 همچنین از desugaring — تبدیل sugar نحوی Java 8+ به کد سازگار با عقب برای سطوح API قدیمی Android پشتیبانی میکند.
طبق Google Android Performance Team (2025)، R8 فشردهسازی کد را 10-15٪ بهتر از ProGuard با قوانین یکسان فراهم میکند. R8 سریعتر است — زمان ساخت 20-30٪ کاهش مییابد. علاوه بر این، R8 کد مرده بیشتری را به دلیل تحلیل در سطح DEX به جای فایلهای class حذف میکند. R8 کاملاً با نحوه قوانین ProGuard سازگار است که مهاجرت را برای توسعهدهنده شفاف میکند.
انتقال از ProGuard به R8 ساده است: در AGP 8.0+ به طور پیشفرض از R8 استفاده میشود. برای پروژههای قدیمی باید ProGuard را از classpath حذف کرده و gradle.properties را بهروزرسانی کنید: android.enableR8=true. قوانین ProGuard در بیشتر موارد بدون تغییر با R8 سازگار هستند. توصیه میشود پس از تغییر، ساخت release را روی تمام دستگاههای هدف آزمایش کنید، زیرا R8 ممکن است کدی را که ProGuard حفظ میکرد حذف کند.
سوالات متداول
رایجترین دلیل — حذف کلاسهایی که از طریق reflection، سریالسازی Gson/Moshi یا کتابخانههای با بارگذاری پویای فایلهای DEX استفاده میشوند. راهحل: قوانین -keep را برای تمام کلاسهایی که از طریق Class.forName() ایجاد میشوند، Parcelable را پیادهسازی میکنند، از طریق JSON سریالسازی میشوند یا با @Inject حاشیهنویسی شدهاند، اضافه کنید. از فایل mapping برای deobfuscation stack trace و تعیین کلاس حذف شده از ساخت استفاده کنید.
فایل mapping پس از ساخت در build/outputs/mapping/release/mapping.txt قرار دارد. فرمت: نام_اصلی -> نام_مبهمشده -> نوع. Android Studio از deobfuscation از طریق Build > Analyze APK پشتیبانی میکند: APK را بارگذاری کنید، stack trace را بچسبانید و نامهای خوانا را دریافت کنید. برای CI/CD، فایلهای mapping را برای هر نسخه در مخزن جداگانه یا ذخیرهسازی ابری نگهداری کنید.
بله، ProGuard فقط باید برای ساختهای release فعال شود. ساختهای debug از minifyEnabled false استفاده میکنند که کامپایل را سریعتر کرده و نام کلاسهای خوانا را برای دیباگر حفظ میکند. در حالت debug، مبهمسازی در اشکالزدایی و اجرای گامبهگام اختلال ایجاد میکند و فشردهسازی تکرارها را کند میکند. برای آزمایش صحت مبهمسازی از ساخت release روی دستگاه فیزیکی استفاده کنید.
هشدارهای ProGuard (WARNING) به مشکلاتی اشاره میکنند که باعث توقف ساخت نمیشوند اما ممکن است نشاندهنده خطاهای اجرایی بالقوه باشند. اگر هشدار منجر به crash نمیشود، -dontwarn را برای کتابخانه مربوطه اضافه کنید. اگر هشدار مربوط به کلاس گمشدهای است که در برنامه استفاده نمیشود، باز هم از -dontwarn استفاده کنید. نادیده گرفتن یکباره همه هشدارها بدون بررسی توصیه نمیشود.
ProGuard — ابزار رایگان با قابلیتهای پایه: فشردهسازی، بهینهسازی، تغییر نام کلاسها و متدها. DexGuard — محصول تجاری از همان Guardsquare که پنهانسازی جریان کنترل، رمزگذاری رشتهها و منابع، محافظت در برابر اشکالزدایی و مبهمسازی منابع را اضافه میکند. DexGuard در برنامههای بانکی و بازیهای با الزامات حفاظتی بالا استفاده میشود.
نتیجهگیری
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید