डिफ़ॉल्ट सेटिंग के साथ ऐप्लिकेशन ऑप्टिमाइज़ेशन की सुविधा चालू करने पर, R8 बड़े पैमाने पर ऑप्टिमाइज़ेशन करता है, ताकि आपको परफ़ॉर्मेंस के ज़्यादा से ज़्यादा फ़ायदे मिल सकें. R8, कोड में बड़े बदलाव करता है. इनमें क्लास, फ़ील्ड, और तरीकों के नाम बदलना, उन्हें एक जगह से दूसरी जगह ले जाना, और उन्हें हटाना शामिल है. अगर आपको लगता है कि इन बदलावों की वजह से गड़बड़ियां आ रही हैं, तो आपको यह बताना होगा कि R8, कोड के किन हिस्सों में बदलाव नहीं करे. इसके लिए, उन हिस्सों को कीप नियमों में शामिल करें.
कीप नियमों की ज़रूरत वाली सामान्य स्थितियां
R8, आपके कोड में मौजूद सभी डायरेक्ट कॉल की पहचान करता है और उन्हें सुरक्षित रखता है. हालांकि, R8, इनडायरेक्ट कोड के इस्तेमाल को नहीं देख सकता. इसकी वजह से, वह ऐसे कोड को हटा सकता है जिसकी आपके ऐप्लिकेशन को ज़रूरत होती है. इससे ऐप्लिकेशन क्रैश हो सकते हैं. इनडायरेक्ट तरीके से इस्तेमाल किए गए ऐसे कोड को सुरक्षित रखने के लिए, R8 को कीप नियमों के ज़रिए निर्देश दें. यहां कुछ सामान्य स्थितियां दी गई हैं, जिनमें आपको कीप नियमों की ज़रूरत पड़ सकती है:
- रिफ़्लेक्शन से ऐक्सेस किया गया कोड: R8 यह नहीं पहचान सकता कि क्लास, फ़ील्ड या तरीकों को रिफ़्लेक्शन से कब ऐक्सेस किया जाता है. उदाहरण के लिए, R8,
Class.getDeclaredMethod()का इस्तेमाल करके, नाम से खोजे गए किसी तरीके याClass.getAnnotation()से वापस लाई गई किसी एनोटेशन की पहचान नहीं कर सकता. इन मामलों में, R8 इन तरीकों और एनोटेशन के नाम बदल सकता है या उन्हें पूरी तरह से हटा सकता है. इससे रनटाइम परClassNotFoundExceptionयाNoSuchMethodExceptionहो सकता है. - Java Native Interface (JNI) से कॉल किया गया कोड: जब नेटिव (C या C++) कोड, Java या Kotlin के किसी तरीके को कॉल करता है या Java या Kotlin कोड, JNI की मदद से C++ कोड को कॉल करता है, तो कॉल, तरीके के नाम के डाइनैमिक स्ट्रिंग लुकअप पर आधारित होता है. R8, डाइनैमिक स्ट्रिंग पर आधारित तरीके के कॉल को नहीं देख सकता. इसलिए, इसके ऑप्टिमाइज़ेशन से आपका कोड टूट सकता है.
यह उन स्थितियों की पूरी सूची नहीं है जिनमें कीप नियमों की ज़रूरत होती है. हालांकि, इन स्थितियों में ज़्यादातर ऐसे मामले शामिल हैं जिनमें आपको कीप नियमों की ज़रूरत पड़ सकती है.
अपने ऐप्लिकेशन में कीप नियम जोड़ने का तरीका
कीप नियमों का कॉन्फ़िगरेशन, आपके इस्तेमाल किए जा रहे Android Gradle प्लगिन (AGP) के वर्शन पर निर्भर करता है.
आम तौर पर, बड़े ऐप्लिकेशन में कई लाइब्रेरी मॉड्यूल में कोड होता है. ऐसे मामलों में, अक्सर कीप नियमों को उस कोड के साथ रखना बेहतर होता है जिन पर वे लागू होते हैं. इसके लिए, उन्हें खास लाइब्रेरी मॉड्यूल में रखें. लाइब्रेरी के लिए कीप नियमों को बनाए रखने में अहम अंतर यह है कि इन नियमों को अपनी लाइब्रेरी मॉड्यूल की
build.gradle.kts (या build.gradle) फ़ाइल में कैसे बताया जाता है. ज़्यादा जानने के लिए, लाइब्रेरी को तैयार करने वालों के लिए ऑप्टिमाइज़ेशन
लेख पढ़ें.
AGP के 9.3 और इसके बाद के वर्शन के लिए
डायरेक्ट्री में, .keep सफ़िक्स वाली किसी फ़ाइल में अपने नियम जोड़ें.src/<variant>/keepRules उदाहरण के लिए, src/main/keepRules/custom-rules.keep. ध्यान दें कि AGP 9.3 और इसके बाद के वर्शन के लिए अपडेट किए गए DSL का इस्तेमाल करने से, कोड और संसाधन, दोनों को ऑप्टिमाइज़ किया जा सकता है. साथ ही, आपको Android के डिफ़ॉल्ट कीप नियमों वाली फ़ाइल (proguard-android-optimize.txt) को साफ़ तौर पर तय करने की ज़रूरत नहीं होती. ऐसा इसलिए, क्योंकि यह डिफ़ॉल्ट रूप से शामिल होती है. हालांकि, इसे साफ़ तौर पर हटाया जा सकता है.
Kotlin
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
}
शानदार
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
}
Android प्लैटफ़ॉर्म के डिफ़ॉल्ट कीप नियमों को छोड़ना (बेहतर सेटिंग)
AGP, Android प्लैटफ़ॉर्म के डिफ़ॉल्ट नियमों का सेट उपलब्ध कराता है. अपने प्रोजेक्ट के कॉन्फ़िगरेशन से इन नियमों को हटाने और सभी कीप नियमों को खुद मैनेज करने के लिए, optimization.keepRules.includeDefault को false पर सेट करें.
Kotlin
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
keepRules {
includeDefault = false // The file with optimization
// rules for the Android platform is included by
// default. To omit this file, set this option to false.
}
}
}
}
}
शानदार
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
keepRules {
includeDefault = false // The file with optimization
// rules for the Android platform is included by
// default. To omit this file, set this option to false.
}
}
}
}
}
AGP के 9.3 से पहले के वर्शन के लिए लेगसी DSL
अपने नियमों को ऐप्लिकेशन मॉड्यूल की रूट डायरेक्ट्री में मौजूद proguard-rules.pro फ़ाइल में जोड़ें. हो सकता है कि यह फ़ाइल पहले से मौजूद हो. अगर ऐसा नहीं है, तो इसे बनाएं. फ़ाइल में मौजूद नियमों को लागू करने के लिए, आपको मॉड्यूल-लेवल की
build.gradle.kts (या build.gradle) फ़ाइल में, उस फ़ाइल का एलान करना होगा.
डिफ़ॉल्ट रूप से, आपकी बिल्ड फ़ाइल में proguard-android-optimize.txt फ़ाइल भी शामिल होती है. इस फ़ाइल में ऐसे नियम शामिल होते हैं जिनकी ज़रूरत ज़्यादातर Android प्रोजेक्ट के लिए होती है. इसलिए, आपको इसे बिल्ड फ़ाइल में रहने देना चाहिए. यह फ़ाइल, proguard-common.txt फ़ाइल पर आधारित होती है और इसमें उसका
कॉन्टेंट भी शामिल होता है.
लेगसी DSL (Kotlin)
android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
// Default file with default optimization rules.
getDefaultProguardFile("proguard-android-optimize.txt"),
...
)
}
}
}
लेगसी DSL (शानदार)
android {
buildTypes {
release {
minifyEnabled = true
shrinkResources = true
// Default file with default optimization rules.
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
...
}
}
}
कीप नियम जोड़ना
कीप नियम जोड़ते समय, ग्लोबल विकल्प शामिल किए जा सकते हैं. साथ ही, अपने कीप नियम भी तय किए जा सकते हैं.
ग्लोबल विकल्प: ग्लोबल विकल्प, सामान्य निर्देश होते हैं. इनसे यह तय होता है कि R8 आपके पूरे कोड बेस पर कैसे काम करता है. ज़्यादा जानने के लिए, ग्लोबल विकल्प लेख पढ़ें.
कीप नियम: कीप नियमों को सावधानी से डिज़ाइन करना ज़रूरी है, ताकि यह पक्का किया जा सके कि आपके ऐप्लिकेशन को अनजाने में तोड़े बिना, कोड ऑप्टिमाइज़ेशन को ज़्यादा से ज़्यादा किया जा सके. कीप नियम लिखने का तरीका जानने के लिए, कीप नियम जोड़ना लेख पढ़ें.
लाइब्रेरी को तैयार करने वालों के लिए कीप नियम
ग्लोबल विकल्पों और कीप नियमों के सिंटैक्स के बारे में जानने के बाद, ज़्यादा जानकारी के लिए लाइब्रेरी को तैयार करने वालों के लिए ऑप्टिमाइज़ेशन लेख पढ़ें.