ProGuard اور R8 Android ایپلیکیشنز کے لیے مبہم کاری، مختصر سازی اور اصلاح کے اوزار ہیں۔ ProGuard، جو 2002 میں بنایا گیا تھا، طویل عرصے تک Java کوڈ کے تحفظ کا حقیقی معیار تھا۔ R8 اس کا جانشین ہے، جسے Google نے تیار کیا اور AGP 3.4 سے Android Gradle Plugin میں شامل کیا گیا۔ دونوں اوزار APK سائز کم کرتے ہیں، مردہ کوڈ ہٹاتے ہیں اور ریورس انجینئرنگ کو پیچیدہ بناتے ہیں۔ Android Developers کے مطابق، R8 تقابلی مبہم کاری معیار کے ساتھ ProGuard سے 2–3 گنا تیزی سے بلڈ کرتا ہے۔
اہم نکات
ProGuard Java بائٹ کوڈ کی مبہم کاری، مختصر سازی، اصلاح اور پیشگی تصدیق کے لیے ایک اوپن سورس ٹول (Apache 2.0) ہے۔ اسے Eric Lafarge نے 2002 میں SourceForge پروجیکٹ کے حصے کے طور پر تیار کیا تھا۔ ProGuard مرتب شدہ Java کلاسز (.class) یا JAR آرکائیوز کو ان پٹ کے طور پر لیتا ہے اور اسی فارمیٹ کی پروسیس شدہ کلاسز تیار کرتا ہے، لیکن چھوٹے سائز اور دوبارہ نامزد کردہ عناصر کے ساتھ۔
ایک طویل عرصے تک، ProGuard Android ایپلیکیشنز کو ریورس انجینئرنگ سے بچانے کا واحد معیار تھا۔ Google نے سرکاری طور پر Android SDK میں اس کے استعمال کی سفارش کی اور SDK ٹولز کے اندر proguard-android-optimize.txt فائل میں ڈیفالٹ کنفیگریشن فراہم کی۔ ProGuard ایک علیحدہ ٹول کے طور پر کام کرتا تھا، جو Java کوڈ کے بائٹ کوڈ میں مرتب ہونے کے بعد اور DEX میں پیکجنگ سے پہلے چلایا جاتا تھا۔
ProGuard چار ترتیب وار مراحل پر مشتمل ہے: shrink (غیر استعمال شدہ کلاسز کا خاتمہ)، optimize (بائٹ کوڈ کی اصلاح — ان لائننگ، مردہ کوڈ کا خاتمہ)، obfuscate (کلاسز، طریقوں اور فیلڈز کو مختصر ناموں میں تبدیل کرنا)، preverify (JVM مطابقت کی جانچ)۔ ہر مرحلہ کنفیگریشن فائلوں سے علیحدہ قواعد کے ذریعے کنٹرول کیا جاتا ہے۔
مبہم کاری کے مرحلے کے دوران، ProGuard ایک میپنگ فائل (mapping.txt) تیار کرتا ہے جو اصل ناموں کو مبہم ناموں سے جوڑتی ہے۔ یہ فائل retrace یوٹیلٹی کے ذریعے ریلیز بلڈز سے کریش لاگ ڈی کوڈ کرنے کے لیے اہم ہے۔ میپنگ فائل کے بغیر، اسٹیک ٹریس حروف a()، b()، c() کے ایک سیٹ میں تبدیل ہو جاتا ہے جس میں اصل سیاق و سباق کو بحال کرنے کا کوئی طریقہ نہیں ہوتا۔
| ProGuard مرحلہ | مقصد | نتیجہ |
|---|---|---|
| Shrink | کال گراف کا تجزیہ اور مردہ کوڈ کا خاتمہ | APK میں کم کلاسز |
| Optimize | طریقوں کی ان لائننگ، غیر استعمال شدہ پیرامیٹرز کا خاتمہ | کوڈ پر عملدرآمد تیز |
| Obfuscate | کلاسز، فیلڈز اور طریقوں کی دوبارہ نامزدگی | ریورس انجینئرنگ سے تحفظ |
| Preverify | JVM کے لیے StackMap خصوصیات کا اضافہ | Java 6+ مطابقت |
R8 Google کا اگلی نسل کا مبہم کاری اور مختصر سازی کا آلہ ہے، جو پہلی بار Android Studio 3.3 (نومبر 2018) میں متعارف کرایا گیا اور AGP 3.4 (اگست 2019) میں معیاری بن گیا۔ ProGuard کے برعکس، R8 D8/R8 کمپائلر کا حصہ ہے جو Java بائٹ کوڈ کو DEX فارمیٹ میں تبدیل کرتا ہے۔ R8 تمام مراحل — مبہم کاری، مختصر سازی اور اصلاح — ایک ہی پاس میں انجام دیتا ہے، بغیر اوزاروں کے درمیان درمیانی فائلیں منتقل کیے۔
Google نے R8 کو دو مقاصد کے ساتھ تیار کیا: بلڈز کو تیز کرنا (ProGuard ایک بیرونی آلے کے طور پر کام کرتا تھا) اور جدید Android اسٹیک (Desugar، Core Library Desugaring، D8) کے ساتھ ہموار انضمام فراہم کرنا۔ R8 Kotlin اور Java میں لکھا گیا ہے اور AOSP (Android اوپن سورس پروجیکٹ) پر R8/Desugar ریپوزٹری کا حصہ ہے۔
R8 کا ایک اہم فائدہ ProGuard قواعد کے ساتھ مکمل پسماندہ مطابقت ہے۔ موجودہ .pro فائلیں بغیر کسی تبدیلی کے کام کرتی ہیں۔ R8 مخصوص ProGuard ہدایات کو بھی سپورٹ کرتا ہے، بشمول -whyareyoukeeping، -printconfiguration اور -printmapping۔ اس کا مطلب ہے کہ ProGuard سے R8 میں منتقلی شفاف ہے: بس AGP اپ ڈیٹ کریں۔
// build.gradle.kts — minifyEnabled کے ذریعے R8 کو فعال کرنا
android {
buildTypes {
getByName("release") {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
// Android SDK سے بنیادی ترتیب
getDefaultProguardFile("proguard-android-optimize.txt"),
// اپنی مرضی کے پروجیکٹ قواعد
"proguard-rules.pro"
)
}
}
}کوڈ ایک معیاری ریلیز بلڈ کنفیگریشن دکھاتا ہے۔ فلیگ isMinifyEnabled = true مبہم کاری اور اصلاح کے لیے R8 کو فعال کرتا ہے۔ isShrinkResources = true اضافی طور پر غیر استعمال شدہ وسائل کو ہٹاتا ہے۔ getDefaultProguardFile SDK سے ڈیفالٹ قواعد لوڈ کرتا ہے، جبکہ proguard-rules.pro میں پروجیکٹ کی مخصوص ترتیبات ہوتی ہیں۔
مبہم کاری سورس کوڈ کو ایسی شکل میں تبدیل کرنے کا عمل ہے جس کا تجزیہ انسانوں کے لیے مشکل ہو لیکن جو مکمل فعالیت کو برقرار رکھتا ہے۔ Android سیاق و سباق میں، مبہم کاری کا مطلب ہے کلاسز، طریقوں اور فیلڈز کو مختصر، بے معنی ناموں میں تبدیل کرنا: com.example.app.auth.LoginManager بن جاتا ہے a.a.a، طریقہ authenticateUser بن جاتا ہے a، فیلڈ userToken بن جاتا ہے b۔
Android APK فائلیں آرکائیوز ہیں جنہیں کسی بھی آرکائیور (ZIP، 7z، WinRAR) سے کھولا جا سکتا ہے۔ مبہم کاری کے بغیر، حملہ آور کو ایپلیکیشن کا مکمل نقشہ مل جاتا ہے: پیکیج نام، کلاسز، طریقے اور فیلڈز۔ jadx یا Bytecode Viewer جیسے اوزار سیکنڈوں میں DEX فائلوں سے تقریباً اصل Java کوڈ بحال کر سکتے ہیں۔ مبہم کاری کوڈ کو ناقابل تسخیر نہیں بناتی، لیکن داخلے کی راہ میں رکاوٹ کو نمایاں طور پر بڑھا دیتی ہے: معنی خیز ناموں کے بجائے، قاری a()، b()، c() دیکھتا ہے۔
عام مبہم کاری کے اہداف: تجارتی منطق کا تحفظ (الگورتھم، حسابی فارمولے)، API چابیاں اور ٹوکن کی چوری میں رکاوٹ، reflection کے ذریعے کلاس کی تبدیلی کو روکنا، اور APK پیچنگ اور ترمیم (ری پیکج اٹیک) کو روکنا۔ عملی طور پر، 70% کام صرف دوبارہ نامزدگی سے حل ہو جاتے ہیں — یہی وجہ ہے کہ ProGuard/R8 استعمال کیا جاتا ہے۔
ذیل میں Retrofit، Gson اور Parcelable کے ساتھ ایک Android پروجیکٹ کے لیے ایک عام proguard-rules.pro فائل ہے۔ -keep قواعد reflection کے ذریعے لائبریری کے آپریشن کے لیے ضروری کلاسز اور طریقوں کو محفوظ رکھتے ہیں۔ ان قواعد کے بغیر، R8 ان کلاسز کو ہٹا یا دوبارہ نامزد کر دے گا جن تک لائبریری سٹرنگ نام سے رسائی حاصل کرتی ہے۔
# =====================
# Retrofit — انٹرفیس کا تحفظ
# =====================
-keep,allowobfuscation,allowshrinking interface retrofit2.** { *; }
-keepattributes Signature, Exceptions
# =====================
# Gson — JSON سیریلائزیشن
# =====================
-keepclassmembers class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keep class *.serialization.** {
<fields>;
}
# =====================
# Parcelable — Creator
# =====================
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}
# =====================
# Logging — ریلیز سے لاگ ہٹانا
# =====================
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(String, int);
public static int v(...);
public static int d(...);
public static int i(...);
public static int w(...);
public static int e(...);
}
# =====================
# Kotlin ڈیٹا کلاسز — کنسٹرکٹرز کا تحفظ
# =====================
-keepclassmembers class * {
@kotlin.Metadata <fields>;
}
# =====================
# Activity — داخلے کا مقام
# =====================
-keep class * extends android.app.Activity {
@android.annotation.SuppressLint <methods>;
}.pro فائل میں ہر ہدایت ایک مخصوص کام حل کرتی ہے۔ -keep پوری کلاس کو ہٹائے یا دوبارہ نامزد کیے جانے سے روکتا ہے۔ -keepclassmembers صرف کلاس ممبران (فیلڈز اور طریقوں) کی حفاظت کرتا ہے لیکن کلاس کو خود ہٹانے کی اجازت دیتا ہے اگر وہ استعمال نہ ہو۔ -assumenosideeffects R8 کو بتاتا ہے کہ میتھڈ کال کا کوئی ضمنی اثر نہیں ہے اور اسے محفوظ طریقے سے ہٹایا جا سکتا ہے۔ ہدایت -keepattributes بائٹ کوڈ میں میٹا ڈیٹا — تشریحات، دستخط، استثنیات — محفوظ رکھتی ہے۔
Retrofit کے لیے قاعدہ -keep,allowobfuscation,allowshrinking R8 کو انٹرفیس کو دوبارہ نامزد کرنے کی اجازت دیتا ہے لیکن ہٹانے کی نہیں۔ یہ ضروری ہے کیونکہ Retrofit ڈائنامک پراکسی (java.lang.reflect.Proxy) کے ذریعے انٹرفیس تک رسائی حاصل کرتا ہے، اور ہٹانے سے رن ٹائم پر ClassNotFoundException پیدا ہوگی۔ اسی طرح، Gson @SerializedName سے تشریح شدہ فیلڈز تک رسائی کے لیے reflection استعمال کرتا ہے — -keepclassmembers کے بغیر فیلڈز کو غیر استعمال شدہ سمجھ کر ہٹا دیا جائے گا۔
مختصر سازی (shrinking) حتمی بلڈ سے غیر استعمال شدہ کوڈ اور وسائل کو ہٹانے کا عمل ہے۔ ProGuard اور R8 انٹری پوائنٹس (Activity، Service، BroadcastReceiver) سے شروع ہو کر کال گراف کا تجزیہ کرتے ہیں اور ان کلاسز اور طریقوں کو ہٹاتے ہیں جن تک کال چین کے ذریعے نہیں پہنچا جا سکتا۔ ShrinkResources ایک اضافی مرحلہ ہے جو res/ (layout، drawable، string، color) سے غیر استعمال شدہ وسائل کو ہٹاتا ہے۔
مختصر سازی لائبریریوں والے بڑے پروجیکٹس میں سب سے زیادہ فائدہ دیتی ہے۔ ایک عام منظر نامہ: ایک پروجیکٹ منسلک لائبریری (مثال کے طور پر Google Play Services) سے 10% کوڈ استعمال کرتا ہے۔ مختصر سازی کے بغیر، تمام لائبریری کوڈ APK میں چلا جاتا ہے۔ مختصر سازی کے ساتھ، R8 لائبریری کوڈ کا 70–90% ہٹا دیتا ہے، صرف حقیقت میں استعمال ہونے والی کلاسز اور طریقوں کو چھوڑ کر۔ یہ براہ راست APK سائز، لوڈنگ ٹائم اور میموری کی کھپت کو متاثر کرتا ہے۔
ShrinkResources میکانزم کوڈ کی مختصر سازی کے ساتھ مل کر کام کرتا ہے۔ R8 کے یہ تعین کرنے کے بعد کہ کون سی کلاسز استعمال ہو رہی ہیں، وسائل کا سکڑاؤ کوڈ سے وسائل کے حوالوں کا تجزیہ کرتا ہے: R.layout.main، R.drawable.icon، getString(R.string.title)۔ تمام وسائل جن کا براہ راست یا بالواسطہ حوالہ نہیں ہے، حتمی APK یا AAB سے ہٹا دیے جاتے ہیں۔ یہ وسائل کی فائل resources.arsc اور res/ فولڈرز کا استعمال کرتے ہوئے کیا جاتا ہے۔
ایک اہم نکتہ: وسائل تک getIdentifier() یا Resources.getResourceName() کے ذریعے سٹرنگ نام سے رسائی حاصل کی جا سکتی ہے، R کلاس کو نظرانداز کرتے ہوئے۔ ایسی صورتوں میں، R8 براہ راست لنک نہیں دیکھتا اور کسی ایسے وسیلہ کو ہٹا سکتا ہے جو حقیقت میں استعمال ہو رہا ہے۔ ایسے وسائل کی حفاظت کے لیے، ہدایت -keep class **.R$* { *; } موجود ہے — یہ R کلاس کے تمام شناخت کنندگان کو محفوظ رکھتی ہے۔
<!-- مثال: وہ وسیلہ جو صرف getIdentifier() کے ذریعے استعمال ہوتا ہے -->
<string name="dynamic_title_welcome">خوش آمدید</string>
<string name="dynamic_title_share">شیئر کریں</string>
<!-- Kotlin کوڈ جو سٹرنگ کے ذریعے رسائی حاصل کرتا ہے -->
<!-- val title = getString(resources.getIdentifier( -->
<!-- \"dynamic_title_${type}\", \"string\", packageName)) -->اس صورت میں، R8 R کلاس میں dynamic_title_welcome کا جامد حوالہ نہیں دیکھتا کیونکہ رسائی متحرک نام کے ساتھ getIdentifier کے ذریعے ہے۔ ایسے وسائل کو محفوظ رکھنے کے لیے، proguard-rules.pro میں ہدایت -keepclassmembers class **.R$string { *; } شامل کریں — یہ تمام R$string کلاسز سے کسی بھی فیلڈ کو ہٹانے سے روکتا ہے۔
| ہدایت | مقصد | مثال |
|---|---|---|
| -keep | کلاس اور اس کے تمام ممبران کو محفوظ رکھتا ہے | -keep class com.example.api.** { *; } |
| -keepclassmembers | صرف کلاس ممبران کو محفوظ رکھتا ہے | -keepclassmembers class * { @SerializedName <fields>; } |
| -keepattributes | بائٹ کوڈ میٹا ڈیٹا محفوظ رکھتا ہے | -keepattributes *Annotation*, Signature |
| -assumenosideeffects | بغیر ضمنی اثرات کے کالز کو ہٹاتا ہے | -assumenosideeffects class Log { d(...); } |
| -dontwarn | انتباہات کو دباتا ہے | -dontwarn com.example.legacy.** |
اس حقیقت کے باوجود کہ R8 ProGuard کا جانشین ہے، اوزاروں کے درمیان فن تعمیر، کارکردگی اور رویے میں بنیادی فرق موجود ہیں۔ Google نے AGP 7.0 سے Android Gradle Plugin میں ProGuard کی سپورٹ سرکاری طور پر ختم کر دی ہے، لیکن ProGuard ان پروجیکٹس میں استعمال ہوتا رہتا ہے جنہیں R8 میں دستیاب نہ ہونے والے مخصوص اصلاحی رویے کی ضرورت ہوتی ہے۔
| خصوصیت | ProGuard | R8 |
|---|---|---|
| ڈویلپر | GuardSquare (Eric Lafarge) | |
| ریلیز سال | 2002 | 2018 (2019 میں مستحکم) |
| فن تعمیر | 4 علیحدہ مراحل (shrink → optimize → obfuscate → preverify) | ایک پاس: shrink + optimize + obfuscate بیک وقت |
| AGP انضمام | بیرونی آلہ، javac کے بعد چلایا جاتا ہے | D8 DEX کمپائلر میں شامل |
| بلڈ رفتار | 2–3 گنا سست | ایک پاس اور مقامی انضمام کی وجہ سے تیز |
| Kotlin سپورٹ | محدود (inline، lambdas، coroutines میں مسائل) | مکمل: coroutines، inline فنکشنز، data class |
| میپنگ فائل | mapping.txt (retrace کے ساتھ مطابقت) | mapping.txt (ایک ہی فارمیٹ) |
| اصلاح کی تخصیص | 60+ اختیارات -optimizationpasses، -optimizations | محدود: زیادہ تر اصلاحیں ڈیفالٹ طور پر فعال |
| سپورٹ کی حیثیت | R8 سے تبدیل (AGP 7.0+ استعمال نہیں کرتا) | فعال ترقی، AOSP کا حصہ |
R8 کوڈ کو ہٹانے میں ProGuard سے زیادہ جارحانہ ہے جسے وہ مردہ سمجھتا ہے۔ اس سے ایسی صورتحال پیدا ہوتی ہے جہاں ڈیبگ بلڈ کام کرتا ہے لیکن ریلیز بلڈ ClassNotFoundException یا NoSuchMethodException کے ساتھ کریش ہوتا ہے۔ عام کیسز: لائبریریاں جو کلاس نام سے reflection استعمال کرتی ہیں (Gson، Moshi، Retrofit، Room، Dagger)؛ ServiceLoader یا java.util.ServiceLoader کالیں؛ ڈائنامک پراکسی (java.lang.reflect.Proxy)؛ مقامی طریقے (JNI)۔ حل یہ ہے کہ ان تمام کلاسز کے لیے -keep شامل کریں جو reflection کے ذریعے بلائی جاتی ہیں۔
# عام reflection مسائل — R8 جامد ربط نہیں دیکھتا
# Room — DAO اور مائیگریشنز کا تحفظ
-keep class * extends androidx.room.RoomDatabase { *; }
-keep class *.DatabaseMigrations { *; }
# Dagger / Hilt — اجزاء کا تحفظ
-keep class * extends dagger.hilt.android.components.** { *; }
# JNI — مقامی طریقوں کو دوبارہ نامزد نہ کرنا
-keepclasseswithmembernames class * {
native <methods>;
}
# Data Binding — Binding کلاسز کا تحفظ
-keep class *.databinding.** { *; }اگر قواعد شامل کرنے کے بعد بھی بلڈ کریش ہوتا ہے، تو proguard-rules.pro میں فلیگ -printconfiguration full-config.txt استعمال کریں۔ R8 ایک مکمل کنفیگریشن فائل تیار کرے گا جو دکھاتی ہے کہ کون سے قواعد لاگو ہوتے ہیں اور کون سی کلاسز محفوظ ہیں۔ ہدایت -whyareyoukeeping class com.example.MyClass بھی مفید ہے — یہ وہ وجہ دکھاتی ہے جس کی بنا پر R8 نے مخصوص کلاس کو محفوظ رکھنے کا فیصلہ کیا۔
ProGuard rules کی مناسب ترتیب رن ٹائم بگز کے بغیر مستحکم مبہم کاری کی کلید ہے۔ ذیل میں ایک نئے پروجیکٹ یا ایسے پروجیکٹ کے لیے مرحلہ وار سیٹ اپ عمل دیا گیا ہے جہاں مبہم کاری غلطیاں پیدا کرتی ہے۔
معیاری Android SDK فائل — proguard-android-optimize.txt کو شامل کرکے شروع کریں۔ اس میں بنیادی Android اجزاء کے قواعد ہیں: Activity، Service، BroadcastReceiver، ContentProvider، View، Fragment۔ یہ فائل SDK فولڈر میں موجود ہے: $ANDROID_HOME/tools/proguard/proguard-android-optimize.txt۔ اگر آپ AGP استعمال کرتے ہیں، تو getDefaultProguardFile اسے خودکار طور پر لوڈ کرے گا۔
ہر مشہور لائبریری کے پاس تجویز کردہ ProGuard قواعد ہیں۔ Retrofit، OkHttp، Glide، Fresco، Coil، Room، Dagger/Hilt، Kotlin Coroutines — سبھی کو مخصوص -keep قواعد کی ضرورت ہوتی ہے۔ عام طور پر قواعد AAR لائبریری میں شامل ہوتے ہیں اور صارف کے تحفظ کے قواعد کے ذریعے خودکار طور پر منسلک ہو جاتے ہیں۔ چیک کریں کہ لائبریری AAR کے اندر proguard.txt فائل فراہم کرتی ہے — یہ ظاہر کرتا ہے کہ قواعد پہلے ہی شامل کیے جا چکے ہیں۔
اشاعت سے پہلے، یقینی بنائیں کہ ریلیز بلڈ کو حقیقی ڈیوائس یا ایمولیٹر پر آزمایا گیا ہے۔ مبہم کاری کے مسائل صرف رن ٹائم پر ظاہر ہوتے ہیں۔ چیک کریں: تصدیق (لاگ ان/رجسٹریشن)، نیٹ ورک سے ڈیٹا لوڈ کرنا، اسکرینوں کے درمیان نیویگیشن، کیمرہ اور گیلری، پش نوٹیفکیشنز، Deeplinks، WebView۔ ریلیز بلڈ میں ہر کریش کو میپنگ فائل کے ساتھ retrace کا استعمال کرتے ہوئے ڈی کوڈ کرنے اور غائب -keep قواعد شامل کرنے کی ضرورت ہوتی ہے۔
میپنگ فائل build/outputs/mapping/release/mapping.txt پر تیار ہوتی ہے۔ یہ فائل محفوظ رکھنا ضروری ہے: اس کے بغیر Google Play Console سے کریش لاگ ڈی کوڈ کرنا ناممکن ہے۔ mapping.txt کو اپنے ورژن کنٹرول سسٹم میں شامل کریں یا اسے CI آرٹیفیکٹ کے طور پر اپ لوڈ کریں۔ Google Play Console uploading mapping.txt کو فعال کرتے ہوئے AAB اپ لوڈ کرنے پر خودکار طور پر میپنگ فائل قبول کرتا ہے۔
ذیل میں proguard-rules.pro فائل میں قواعد کے ہر گروپ کے لیے تبصروں کے ساتھ ایک مکمل مبہم کاری سیٹ اپ ورک فلو ہے۔
# ===========================================
# proguard-rules.pro — مکمل مثال
# ===========================================
# --- عمومی ترتیبات ---
-keepattributes *Annotation*, Signature, Exceptions, InnerClasses, EnclosingMethod
-dontpreverify
# --- Android اجزاء ---
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.Fragment
-keep public class * extends androidx.fragment.app.Fragment
-keep public class * extends android.view.View
# --- OkHttp / Retrofit ---
-dontwarn okhttp3.**
-dontwarn okio.**
-keep class retrofit2.** { *; }
-keepattributes Exceptions
# --- Gson / Moshi ---
-keepclassmembers class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keep class com.google.gson.** { *; }
# --- Firebase ---
-keep class com.google.firebase.** { *; }
-keep class com.google.android.gms.** { *; }
# --- Kotlin Coroutines ---
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
# --- سیریلائزیشن ---
-keepclassmembers class * implements java.io.Serializable {
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# --- صرف R8: زبردستی تحفظ ---
# (ProGuard اس ہدایت کو نظرانداز کرتا ہے)
-keep,allowobfuscation class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}ترتیب کے بعد، بلڈ چلائیں: ./gradlew assembleRelease۔ تصدیق کریں کہ build/outputs/mapping/release/ میں فائلیں ظاہر ہوئیں: mapping.txt (اصل سے مبہم ناموں کا نقشہ)، seeds.txt (-keep قواعد سے محفوظ کردہ کلاسز)، usage.txt (مختصر سازی کے دوران ہٹائی گئی کلاسز)۔ مبہم کاری کے بعد APK سائز منسلک لائبریریوں کی تعداد کے لحاظ سے 20–50% کم ہونا چاہیے۔
اکثر پوچھے گئے سوالات
R8 ProGuard کا جانشین ہے، جسے Google نے تیار کیا ہے۔ R8 مبہم کاری، مختصر سازی اور اصلاح ایک ہی پاس میں کرتا ہے، ProGuard سے 2–3 گنا تیز کام کرتا ہے اور براہ راست Android Gradle Plugin میں ضم ہے۔ ProGuard چار علیحدہ مراحل استعمال کرتا ہے اور بیرونی عملدرآمد کی ضرورت ہوتی ہے۔ AGP 7.0 سے، ProGuard استعمال نہیں ہوتا — ڈیفالٹ طور پر R8 کام کرتا ہے۔
ہاں، R8 وہی ProGuard rules (.pro فائلیں) استعمال کرتا ہے۔ ہدایات -keep، -keepclassmembers، -keepattributes، -assumenosideeffects ایک جیسی کام کرتی ہیں۔ بنیادی قواعد Android SDK سے proguard-android-optimize.txt میں آتے ہیں، جبکہ لائبریری کے مخصوص قواعد (Retrofit، Room، Gson) پروجیکٹ کے proguard-rules.pro میں شامل کیے جاتے ہیں۔ ان قواعد کے بغیر، R8 ان کلاسز کو ہٹا سکتا ہے جو reflection کے ذریعے کام کرنے والی لائبریریوں کے لیے ضروری ہیں۔
R8 AGP 3.4 سے Android Gradle Plugin میں ڈیفالٹ طور پر فعال ہے۔ مختصر سازی کو فعال کرنے کے لیے، build.gradle.kts فائل کے release buildType بلاک میں isMinifyEnabled = true سیٹ کریں۔ اضافی فلیگ isShrinkResources = true غیر استعمال شدہ وسائل کو ہٹانے کو فعال کرتا ہے۔ gradle.properties میں، آپ android.enableR8=false کے ذریعے R8 کو زبردستی غیر فعال کر سکتے ہیں، لیکن یہ تجویز نہیں کیا جاتا — R8 تیز اور زیادہ مستحکم ہے۔
مبہم کاری — کلاسز، طریقوں اور فیلڈز کو مختصر بے معنی ناموں (a، b، c) میں تبدیل کرنا۔ کلاس com.example.app.auth.LoginManager a.a.a بن جاتی ہے، طریقہ authenticateUser a بن جاتا ہے۔ یہ ایپلیکیشن کے ریورس انجینئرنگ کو پیچیدہ بناتا ہے لیکن عملدرآمد کی منطق کو متاثر نہیں کرتا۔ ProGuard اور R8 صرف ان عناصر کو دوبارہ نامزد کرتے ہیں جو -keep قواعد سے محفوظ نہیں ہیں۔ میپنگ فائل کریش لاگ ڈی کوڈ کرنے کے لیے اصل اور مبہم ناموں کی مطابقت کو محفوظ رکھتی ہے۔
اسٹیک ٹریس ڈی کوڈ کرنے کے لیے، retrace یوٹیلٹی (ProGuard/R8 SDK کا حصہ) استعمال کریں۔ کمانڈ: retrace mapping.txt crash-stacktrace.txt۔ میپنگ فائل build/outputs/mapping/release/mapping.txt پر واقع ہے۔ Google Play Console AAB شائع کرتے وقت mapping.txt اپ لوڈ کرنے کی بھی حمایت کرتا ہے — کریش لاگ خودکار طور پر کنسول میں ڈی کوڈ ہو جاتے ہیں۔ میپنگ فائل کے بغیر، اسٹیک ٹریس میں صرف a.b.c() جیسے مبہم نام ہوں گے، جو ڈیبگنگ کے لیے بیکار ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں