ऐप्लिकेशन ऑप्टिमाइज़ करने की सुविधा चालू करने पर, R8 के अलग-अलग वर्शन के लिए ऑप्टिमाइज़र का डिफ़ॉल्ट व्यवहार अलग-अलग होता है.
- AGP 9.3 और इसके बाद के वर्शन में उपलब्ध अपडेट किए गए डीएसएल के साथ, ऑप्टिमाइज़ेशन चालू होने पर संसाधन कम करने की सुविधा डिफ़ॉल्ट रूप से चालू होती है. ध्यान दें कि लेगसी डीएसएल का इस्तेमाल अब भी किया जा सकता है. इसके लिए, कोड और संसाधन ऑप्टिमाइज़ेशन को अलग से चालू करना होता है.
AGP 9.3 से पहले के वर्शन के लिए,
isShrinkResources = trueसेटिंग, ऑप्टिमाइज़र को ऐसे संसाधनों को हटाने का निर्देश देती है जिनका इस्तेमाल नहीं किया जाता. इससे आपके ऐप्लिकेशन का साइज़ कम करने में मदद मिलती है. संसाधन कम करने की सुविधा, कोड कम करने की सुविधा के साथ ही काम करती है. इसलिए, अगर संसाधनों को ऑप्टिमाइज़ किया जा रहा है, तोisMinifyEnabled = trueभी सेट करें.
AGP 9.3+ (Kotlin)
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
AGP 9.3+ (Groovy)
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
लेगसी डीएसएल (Kotlin)
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
...
}
}
लेगसी डीएसएल (Groovy)
buildTypes {
release {
minifyEnabled = true
shrinkResources = true
...
}
}
अगर आपको कुछ संसाधनों को रखना है या हटाना है, तो अपने प्रोजेक्ट के संसाधनों में एक्सएमएल keep फ़ाइल बनाएं. उदाहरण के लिए, res/raw/keep_my_package.xml. कीप फ़ाइल में ये कॉम्पोनेंट होते हैं:
<resources>टैग — इसमें सभी चाइल्ड रिसॉर्स एलिमेंट और keep/discard एट्रिब्यूट शामिल होते हैं.tools:keepएट्रिब्यूट — यह कॉमा लगाकर अलग की गई लिस्ट में उन संसाधनों के नाम स्वीकार करता है जिन्हें बनाए रखना हैtools:discardएट्रिब्यूट — इसमें कॉमा लगाकर अलग की गई लिस्ट में उन संसाधनों के नाम डाले जाते हैं जिन्हें खारिज करना है
एक ही फ़ोल्डर में मौजूद कई संसाधनों को रेफ़रंस करने के लिए, तारांकन वाले वर्ण का इस्तेमाल वाइल्डकार्ड के तौर पर करें. उदाहरण के लिए:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
tools:discard="@layout/unused2" />
संसाधनों को मिटाने के बजाय, उन्हें हटाने के लिए यह तय करना कि किन संसाधनों को हटाना है, शायद ज़रूरी न लगे. हालांकि, बिल्ड के अलग-अलग वर्शन इस्तेमाल करते समय, संसाधनों को हटाना फ़ायदेमंद हो सकता है.
बिल्ड के खास वैरिएंट को टारगेट करना
अगर आपको सिर्फ़ कुछ बिल्ड वैरिएंट में मौजूद संसाधनों को हटाना है, तो अपने सभी संसाधनों को सामान्य प्रोजेक्ट डायरेक्ट्री में रखें. इसके बाद, वैरिएंट की संसाधन डायरेक्ट्री में, हर बिल्ड वैरिएंट के लिए अलग keep_my_package_build_variant.xml फ़ाइल बनाएं. कीप फ़ाइल में, उन संसाधनों को मैन्युअल तरीके से बताएं जिन्हें कोड में इस्तेमाल किया जा रहा है (और इसलिए, श्रिंकर उन्हें नहीं हटाता). हालांकि, आपको पता है कि दिए गए बिल्ड के वैरिएंट के लिए उनका इस्तेमाल नहीं किया जाएगा.
इस्तेमाल न किए गए वैकल्पिक संसाधन हटाना
ऑप्टिमाइज़र सिर्फ़ उन संसाधनों को हटाता है जिन्हें आपके ऐप्लिकेशन कोड में रेफ़रंस नहीं दिया गया है. इसका मतलब है कि ऑप्टिमाइज़र, अलग-अलग डिवाइस कॉन्फ़िगरेशन के लिए वैकल्पिक संसाधनों को नहीं हटाएगा.
अपने ऐप्लिकेशन के मॉड्यूल की build.gradle फ़ाइल में, Android Gradle resConfigs प्रॉपर्टी का इस्तेमाल करके, उन वैकल्पिक रिसॉर्स फ़ाइलों को हटाएं जिनकी आपके ऐप्लिकेशन को ज़रूरत नहीं है.
उदाहरण के लिए, अगर ऐसी लाइब्रेरी का इस्तेमाल किया जा रहा है जिसमें भाषा से जुड़े संसाधन शामिल हैं (जैसे कि Google Play Services), तो आपके ऐप्लिकेशन में उन लाइब्रेरी में मौजूद मैसेज के लिए, अनुवाद की गई सभी भाषा स्ट्रिंग शामिल होंगी. भले ही, आपके ऐप्लिकेशन के बाकी हिस्से का अनुवाद उन भाषाओं में किया गया हो या नहीं. अगर आपको सिर्फ़ उन भाषाओं को शामिल करना है जिनमें आपका ऐप्लिकेशन आधिकारिक तौर पर काम करता है, तो resConfigs प्रॉपर्टी का इस्तेमाल करके उन भाषाओं के बारे में बताएं.
जिन भाषाओं के लिए संसाधन नहीं दिए गए हैं उन्हें हटा दिया जाता है.
यहां दिए गए स्निपेट में, भाषा के संसाधनों को सिर्फ़ अंग्रेज़ी और फ़्रेंच तक सीमित करने का तरीका बताया गया है:
android {
defaultConfig {
...
resourceConfigurations.addAll(listOf("en", "fr"))
}
}
या
android {
defaultConfig {
...
resConfigs "en", "fr"
}
}
Android ऐप्लिकेशन बंडल (एएबी) फ़ॉर्मैट का इस्तेमाल करके कोई ऐप्लिकेशन पब्लिश करने पर, डिफ़ॉल्ट रूप से सिर्फ़ वे भाषाएं डाउनलोड होती हैं जो उपयोगकर्ता के डिवाइस पर कॉन्फ़िगर की गई हैं. ऐसा तब होता है, जब उपयोगकर्ता ऐप्लिकेशन इंस्टॉल करता है. इसी तरह, डाउनलोड में सिर्फ़ वे संसाधन शामिल होते हैं जो डिवाइस की स्क्रीन डेंसिटी से मेल खाते हैं. साथ ही, इसमें वे नेटिव लाइब्रेरी भी शामिल होती हैं जो डिवाइस के एबीआई से मेल खाती हैं. ज़्यादा जानकारी के लिए, कॉन्फ़िगरेशन वाले APK के टाइप को फिर से चालू या बंद करना लेख पढ़ें.
APK के साथ रिलीज़ किए जा रहे लेगसी ऐप्लिकेशन (अगस्त 2021 से पहले बनाए गए) के लिए, स्क्रीन डेंसिटी या ABI संसाधनों को अपनी पसंद के मुताबिक बनाया जा सकता है. इसके लिए, आपको एक से ज़्यादा APK बनाने होंगे. ये APK, अलग-अलग डिवाइस कॉन्फ़िगरेशन को टारगेट करते हैं.
संसाधन मर्ज करते समय टकराव से बचना
डिफ़ॉल्ट रूप से, Android Gradle प्लगिन (एजीपी), एक जैसे नाम वाले संसाधनों को मर्ज कर देता है. जैसे, अलग-अलग संसाधन फ़ोल्डर में मौजूद एक ही नाम वाले ड्रॉएबल.
इस व्यवहार को shrinkResources प्रॉपर्टी कंट्रोल नहीं करती है. इसे बंद भी नहीं किया जा सकता, क्योंकि यह व्यवहार ज़रूरी है. ऐसा इसलिए, ताकि जब कई संसाधनों का नाम वही हो जिसे आपका कोड रेफ़र कर रहा है, तो गड़बड़ियों से बचा जा सके.
रिसॉर्स मर्ज करने की सुविधा सिर्फ़ तब काम करती है, जब दो या इससे ज़्यादा फ़ाइलों में एक जैसा रिसॉर्स नाम, टाइप, और क्वालिफ़ायर हो. AGP, डुप्लीकेट फ़ाइलों में से सबसे अच्छी फ़ाइल चुनता है. यह फ़ाइल, नीचे दिए गए प्राथमिकता क्रम के आधार पर चुनी जाती है. इसके बाद, AGP सिर्फ़ उस फ़ाइल को AAPT को भेजता है, ताकि उसे फ़ाइनल बिल्ड आर्टफ़ैक्ट में शामिल किया जा सके.
AGP, इन जगहों पर डुप्लीकेट संसाधनों की जांच करता है:
- मुख्य सोर्स सेट से जुड़े मुख्य संसाधन, आम तौर पर
src/main/res/में मौजूद होते हैं - बिल्ड का तरीका और बिल्ड फ़्लेवर से वैरिएंट ओवरले
- लाइब्रेरी प्रोजेक्ट की डिपेंडेंसी
AGP, डुप्लीकेट संसाधनों को इस क्रम में मर्ज करता है:
उदाहरण के लिए, अगर कोई डुप्लीकेट संसाधन आपके मुख्य संसाधनों और बिल्ड फ़्लेवर, दोनों में दिखता है, तो Gradle, बिल्ड फ़्लेवर में मौजूद संसाधन को चुनता है.
अगर एक जैसे संसाधन, एक ही source set में दिखते हैं, तो Gradle उन्हें मर्ज नहीं कर सकता. साथ ही, संसाधन मर्ज करने से जुड़ी गड़बड़ी दिखाता है. ऐसा तब हो सकता है, जब आपने अपने मॉड्यूल build.gradle की sourceSet प्रॉपर्टी में एक से ज़्यादा सोर्स सेट तय किए हों. उदाहरण के लिए, अगर src/main/res/ और src/main/res2/, दोनों में एक जैसे संसाधन शामिल हों.
इस्तेमाल नहीं किए जाने वाले रिसॉर्स को हटाने की प्रोसेस से जुड़ी समस्या हल करना
संसाधनों को छोटा करने पर, बनाएं विंडो में, ऐप्लिकेशन से हटाए गए संसाधनों की खास जानकारी दिखती है. Gradle से टेक्स्ट के रूप में ज़्यादा जानकारी दिखाने के लिए, विंडो के बाईं ओर मौजूद व्यू टॉगल करें पर क्लिक करें. उदाहरण के लिए:
:android:shrinkDebugResources
Removed unused resources: Resource data reduced from 2570KB to 1711KB: Removed 33%
:android:validateDebugSigning
Gradle, resources.txt में <module-name>/build/outputs/mapping/release/ नाम की एक डाइग्नोस्टिक फ़ाइल भी बनाता है. यह वही फ़ोल्डर होता है जिसमें ProGuard की आउटपुट फ़ाइलें होती हैं. इस फ़ाइल में यह जानकारी शामिल होती है कि कौनसे संसाधन, दूसरे संसाधनों को रेफ़रंस देते हैं और किन संसाधनों का इस्तेमाल किया गया है या उन्हें हटाया गया है.
उदाहरण के लिए, यह पता लगाने के लिए कि @drawable/ic_plus_anim_016 आपके ऐप्लिकेशन में अब भी क्यों मौजूद है, resources.txt फ़ाइल खोलें और उस फ़ाइल का नाम खोजें. आपको दिख सकता है कि
इसे किसी दूसरे संसाधन से लिया गया है:
16:25:48.005 [QUIET] [system.out] @drawable/add_schedule_fab_icon_anim : reachable=true
16:25:48.009 [QUIET] [system.out] @drawable/ic_plus_anim_016
अब आपको यह जानने की ज़रूरत है कि @drawable/add_schedule_fab_icon_anim तक पहुंचा जा सकता है या नहीं;
अगर ऊपर की ओर खोज की जाती है, तो आपको resources.txt में रूट तक पहुंचने वाले संसाधन ये हैं: हेडिंग के नीचे संसाधन की सूची दिखेगी.
इसका मतलब है कि add_schedule_fab_icon_anim का कोड रेफ़रंस मौजूद है. यानी, R.drawable का आईडी, ऐक्सेस किए जा सकने वाले कोड में मिला है.
अगर आपने स्ट्रिक्ट चेकिंग का इस्तेमाल नहीं किया है, तो रिसॉर्स आईडी को 'पहुंचा जा सकता है' के तौर पर मार्क किया जा सकता है. ऐसा तब होता है, जब ऐसे स्ट्रिंग कॉन्स्टेंट मौजूद हों जिनका इस्तेमाल, डाइनैमिक तरीके से लोड किए गए रिसॉर्स के नाम बनाने के लिए किया जा सकता है. ऐसे में, अगर संसाधन के नाम के लिए बिल्ड आउटपुट खोजा जाता है, तो आपको इस तरह का मैसेज दिख सकता है:
10:32:50.590 [QUIET] [system.out] Marking drawable:ic_plus_anim_016:2130837506
used because its format-string matches string pool constant ic_plus_anim_%1$d.
अगर आपको इनमें से कोई स्ट्रिंग दिखती है और आपको यकीन है कि दी गई संसाधन को डाइनैमिक तरीके से लोड करने के लिए स्ट्रिंग का इस्तेमाल नहीं किया जा रहा है, तो अपनी कीप फ़ाइल में tools:discard एट्रिब्यूट का इस्तेमाल करें. इससे बिल्ड सिस्टम को संसाधन हटाने के बारे में सूचना मिलेगी.