ग्लोबल विकल्प जोड़ना

R8, ग्लोबल विकल्प उपलब्ध कराता है. ये विकल्प, पूरे ऐप्लिकेशन में R8 के ऑप्टिमाइज़ेशन में बदलाव करते हैं या हर कीप नियम पर असर डालते हैं. इन विकल्पों को proguard-rules.pro फ़ाइल में सेव किया जाता है. साथ ही, इसमें डेटा को सुरक्षित रखने से जुड़े नियम भी सेव किए जाते हैं. इन ग्लोबल विकल्पों में से कुछ, बेहतर ऑप्टिमाइज़ेशन के लिए कॉन्फ़िगर किए जाते हैं. वहीं, अन्य विकल्प ऑप्टिमाइज़ेशन के कुछ पहलुओं को बंद कर देते हैं.

ज़्यादा ऑप्टिमाइज़ेशन के लिए ग्लोबल विकल्प

यहां दिए गए ग्लोबल विकल्पों की मदद से, बेहतर तरीके से ऑप्टिमाइज़ेशन किया जा सकता है:

  • -repackageclasses [<optional-package-name>]: ऐप्लिकेशन का साइज़ कम करने के लिए, क्लास को एक पैकेज में फिर से पैक करता है. अगर आपने पैकेज का नाम नहीं दिया है, तो क्लास को बिना नाम वाले डिफ़ॉल्ट पैकेज में ले जाया जाता है. ऐप्लिकेशन के लिए, यह सेटिंग इस्तेमाल करने का सुझाव दिया जाता है. इसकी वजह यह है कि इससे क्लास के नामों से पैकेज प्रीफ़िक्स हट जाता है और DEX फ़ाइलें छोटी हो जाती हैं.
  • -allowaccessmodification: इससे R8 को क्लास, फ़ील्ड, और तरीकों की जानकारी को बदलने (आम तौर पर बढ़ाने) की अनुमति मिलती है, ताकि ज़्यादा ऑप्टिमाइज़ेशन किया जा सके. proguard-android-optimize.txt का इस्तेमाल करने पर, यह सुविधा चालू हो जाती है. Android Gradle प्लगिन (AGP) 8.2 से, R8 के साथ पूरा ऑप्टिमाइज़ेशन चालू करने पर, यह डिफ़ॉल्ट कॉन्फ़िगरेशन होता है.
  • -processkotlinnullchecks [level]: इससे R8, Kotlin Intrinsics के null चेक को बदल सकता है. इसके लिए, वह गड़बड़ी के मैसेज को हटा सकता है या null चेक को पूरी तरह से हटा सकता है.

    level की वैल्यू को सबसे कम से लेकर सबसे ज़्यादा तक के क्रम में लगाने पर, ये असर दिखते हैं:

    • keep से जांचों में कोई बदलाव नहीं होता.
    • remove_message, जांच के हर तरीके के कॉल को कॉल के पहले आर्ग्युमेंट पर getClass() के कॉल में बदलता है. इससे, शून्य की जांच को असरदार तरीके से बनाए रखा जाता है, लेकिन बिना किसी मैसेज के.
    • remove से जांचें पूरी तरह हट जाती हैं.

    डिफ़ॉल्ट रूप से, R8 remove_message का इस्तेमाल करता है. -processkotlinnullchecks की कोई भी जानकारी, इस जानकारी को बदल देती है. एक से ज़्यादा बार तय की गई वैल्यू में से सबसे सटीक वैल्यू का इस्तेमाल किया जाता है.

    -processkotlinnullchecks AGP 9.0.0 से काम करता है.

यहां अतिरिक्त ऑप्टिमाइज़ेशन की सुविधा चालू करके कॉन्फ़िगरेशन करने का एक उदाहरण दिया गया है:

-repackageclasses
-allowaccessmodification

ऑप्टिमाइज़ेशन को सीमित करने के लिए ग्लोबल विकल्प

यहां दिए गए ग्लोबल विकल्पों की मदद से, ऐप्लिकेशन ऑप्टिमाइज़ेशन की कुछ सुविधाओं को बंद किया जा सकता है. ये विकल्प तब काम आते हैं, जब आपको अपने कीप नियमों को बेहतर बनाना हो या पहली बार R8 चालू करना हो.

  • -dontoptimize: यह कोड ऑप्टिमाइज़ेशन को रोकता है. जैसे, मेथड इनलाइनिंग. इस विकल्प का इस्तेमाल डेवलपमेंट के दौरान किया जा सकता है. हालांकि, इसका इस्तेमाल प्रोडक्शन बिल्ड में नहीं किया जाना चाहिए.
  • -dontshrink: इससे बिना रेफ़रंस वाले कोड को हटाने और कोड को ऑप्टिमाइज़ करने से रोका जाता है. इस विकल्प का इस्तेमाल डेवलपमेंट के दौरान किया जा सकता है. हालांकि, प्रोडक्शन बिल्ड में इसका इस्तेमाल नहीं किया जाना चाहिए.
  • -dontobfuscate: इससे क्लास और मेथड के नाम छोटे नहीं किए जाते. डीबग करने के दौरान, अस्पष्ट करने की सुविधा को बंद करना खास तौर पर मददगार हो सकता है, ताकि स्टैक ट्रेस को आसानी से पढ़ा जा सके. इस विकल्प का इस्तेमाल डेवलपमेंट के दौरान किया जा सकता है. हालांकि, प्रोडक्शन बिल्ड में इसका इस्तेमाल नहीं किया जाना चाहिए.
  • -keepattributes <attributes>: यह कॉमा से अलग किए गए एट्रिब्यूट की ऐसी सूची स्वीकार करता है जिन्हें सुरक्षित रखना चाहिए. अगर डिफ़ॉल्ट proguard-android-optimize.txt का इस्तेमाल नहीं किया जा रहा है, तो R8, RuntimeVisibleAnnotations और Signature के साथ-साथ सभी एट्रिब्यूट हटा देता है. हालांकि, अगर रिफ़्लेक्शन जैसे मामलों में इन एट्रिब्यूट की ज़रूरत होती है, तो इन्हें बनाए रखना फ़ायदेमंद हो सकता है. जिन एट्रिब्यूट की वैल्यू दी जा सकती है उनकी सूची देखने के लिए, एट्रिब्यूट बनाए रखें लेख पढ़ें.

एट्रिब्यूट बनाए रखें

एट्रिब्यूट, आपके कोड के अलग-अलग हिस्सों से जुड़ी अतिरिक्त जानकारी होती है. एट्रिब्यूट, आपके कोड से एनोटेशन और सामान्य सिग्नेचर जैसी जानकारी सेव करते हैं.

कुछ रिफ़्लेक्टिव ऑपरेशन के लिए, खास एट्रिब्यूट को सेव करके रखना ज़रूरी होता है, ताकि उन्हें सही तरीके से लागू किया जा सके. उदाहरण के लिए:

  • getEnclosingMethod() या getDeclaredClasses() का इस्तेमाल करके, इनर या आउटर क्लास स्ट्रक्चर को ऐक्सेस करते समय, EnclosingMethod और InnerClasses एट्रिब्यूट की ज़रूरत होती है.
  • getTypeParameters() का इस्तेमाल करके सामान्य हस्ताक्षर ऐक्सेस करते समय, Signature एट्रिब्यूट की ज़रूरत होती है.
  • getAnnotation() का इस्तेमाल करके एनोटेशन ऐक्सेस करते समय, RuntimeVisibleAnnotations एट्रिब्यूट का होना ज़रूरी है.

आम तौर पर ज़रूरी एट्रिब्यूट

डिफ़ॉल्ट Proguard फ़ाइल (proguard-android-optimize.txt या proguard-android.txt) का इस्तेमाल करते समय, Android Gradle प्लगिन (AGP) इन एट्रिब्यूट को सेव रखता है. ध्यान दें कि इनमें से कुछ एट्रिब्यूट के लिए, AGP के नए वर्शन की ज़रूरत होती है:

एट्रिब्यूट ब्यौरा
AnnotationDefault यह एट्रिब्यूट, एनोटेशन टाइप में मौजूद होता है. साथ ही, यह एनोटेशन एलिमेंट की डिफ़ॉल्ट वैल्यू सेव करता है.

ध्यान दें: AGP 7.1 के बाद से, यह एट्रिब्यूट डिफ़ॉल्ट रूप से मौजूद होता है. इसे सिर्फ़ AGP के पुराने वर्शन का इस्तेमाल करने वाले ऐप्लिकेशन में साफ़ तौर पर रखा जाना चाहिए.
EnclosingMethod यह एट्रिब्यूट, ऐसी इनर क्लास में मौजूद होता है जो लोकल या ऐनॉनमस क्लास नहीं होती हैं. इससे उस तरीके या इनिशियलाइज़र की पहचान होती है जिसमें क्लास मौजूद है.
InnerClasses यह एट्रिब्यूट, किसी दूसरी क्लास में तय की गई नेस्ट की गई क्लास (इनर क्लास, स्टैटिक नेस्टेड क्लास, लोकल क्लास, और ऐनॉनमस क्लास) के बारे में जानकारी रिकॉर्ड करता है.
LineNumberTable यह एट्रिब्यूट, बाइटकोड निर्देशों को ओरिजनल सोर्स फ़ाइल में मौजूद उनके लाइन नंबर से मैप करता है.

ध्यान दें: Android Gradle Plugin (AGP) 8.6 के बाद से, यह एट्रिब्यूट डिफ़ॉल्ट रूप से रखा जाता है. इसे सिर्फ़ AGP के पुराने वर्शन इस्तेमाल करने वाले ऐप्लिकेशन में साफ़ तौर पर रखना ज़रूरी है.
RuntimeVisibleAnnotations यह एट्रिब्यूट, ऐसे एनोटेशन सेव करता है जो रिफ़्लेक्शन के ज़रिए रनटाइम में दिखते हैं.

आम तौर पर, अगर एनोटेशन का इस्तेमाल रनटाइम में किया जाता है, तो यह *Annotation एट्रिब्यूट से मिलने वाला ऐसा एनोटेशन होता है जिसकी ज़रूरत ऐप्लिकेशन और लाइब्रेरी के उपभोक्ता नियमों में होती है.
RuntimeVisibleParameterAnnotations यह एट्रिब्यूट, एनोटेशन सेव करता है. ये एनोटेशन, किसी तरीके के पैरामीटर पर रिफ़्लेक्शन के ज़रिए रनटाइम पर दिखते हैं.
RuntimeVisibleTypeAnnotations यह एट्रिब्यूट, एनोटेशन सेव करता है. ये एनोटेशन, सिर्फ़ टाइप के इस्तेमाल पर लागू होते हैं, न कि सिर्फ़ एलान पर. यह एट्रिब्यूट रनटाइम में दिखता है.
Signature यह एट्रिब्यूट, क्लास, तरीकों, और फ़ील्ड के लिए ज़्यादा सामान्य टाइप सिग्नेचर सेव करता है. खास तौर पर, जब वे जेनरिक (जैसे कि List<String>) का इस्तेमाल करते हैं.
SourceFile इस एट्रिब्यूट में, सोर्स फ़ाइल (.kt या .java फ़ाइल) का नाम सेव होता है. यह वह फ़ाइल होती है जिससे क्लास को कंपाइल किया गया था. इसका इस्तेमाल मुख्य रूप से डिबगर करते हैं. इससे कंपाइल किए गए Java कोड में एक-एक करके आगे बढ़ते समय, सोर्स कोड की ओरिजनल लाइनें दिखती हैं. इससे डेवलपर को, लिखे गए कोड के हिसाब से एक्ज़ीक्यूशन को वापस ट्रैक करने में मदद मिलती है.

ध्यान दें: AGP 8.2 से, इस एट्रिब्यूट को डिफ़ॉल्ट रूप से रखा जाता है. इसे सिर्फ़ AGP के पुराने वर्शन का इस्तेमाल करने वाले ऐप्लिकेशन में साफ़ तौर पर रखना ज़रूरी है.

proguard-android-optimize.txt का इस्तेमाल करने वाले ऐप्लिकेशन के लिए, AGP के तय किए गए डेटा को बनाए रखने के नियम ज़्यादातर मामलों में सही होते हैं. हालांकि, अगर आपको किसी लाइब्रेरी के लिए कोड लिखना है, तो आपको अपनी लाइब्रेरी के लिए ज़रूरी सभी एट्रिब्यूट, उपयोगकर्ता के लिए बनाए गए नियमों में बताने चाहिए. भले ही, वे इस सूची में तय किए गए हों. इससे यह पक्का होता है कि अगर डेवलपर proguard-android-optimize.txt को शामिल नहीं करते हैं, तो आपकी लाइब्रेरी मज़बूत हो.

Keep के अन्य एट्रिब्यूट

आपको बनाए रखने के लिए अतिरिक्त एट्रिब्यूट तय करने का विकल्प मिलता है. हालांकि, रिफ़्लेक्टिव या जेएनआई ऐक्सेस के ज़्यादातर मामलों में इनकी ज़रूरत नहीं होती. हालांकि, लाइब्रेरी को ऑप्टिमाइज़ करते समय, इनमें से कुछ का इस्तेमाल अब भी अक्सर किया जा सकता है.

एट्रिब्यूट ब्यौरा
MethodParameters इस एट्रिब्यूट से, किसी तरीके के पैरामीटर के बारे में जानकारी मिलती है. खास तौर पर, उनके नाम और ऐक्सेस फ़्लैग के बारे में.
Exceptions इस एट्रिब्यूट में, उन चेक किए गए अपवादों की सूची होती है जिन्हें थ्रो करने के लिए किसी तरीके का एलान किया जाता है.

आम तौर पर, इस एट्रिब्यूट का इस्तेमाल ऐप्लिकेशन के लिए नहीं किया जाता. लाइब्रेरी के लेखकों के लिए, इसका इस्तेमाल आम तौर पर उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े नियमों में नहीं किया जाता. हालांकि, लाइब्रेरी बनाते समय इसका इस्तेमाल अक्सर किया जाता है. लाइब्रेरी को ऑप्टिमाइज़ करने के बारे में जानकारी के लिए, लाइब्रेरी के लेखकों के लिए ऑप्टिमाइज़ेशन लेख पढ़ें.
RuntimeInvisibleAnnotations यह एट्रिब्यूट, ऐसे एनोटेशन सेव करता है जो क्लास, फ़ील्ड या तरीके पर रनटाइम में रिफ़्लेक्शन के साथ नहीं दिखते.

ऐप्लिकेशन डेवलपर को इस एट्रिब्यूट को नहीं रखना चाहिए. लाइब्रेरी के लेखकों के लिए, यह एट्रिब्यूट उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े नियमों में काम का नहीं है. हालांकि, लाइब्रेरी बनाते समय इसका इस्तेमाल अक्सर किया जाता है. लाइब्रेरी को ऑप्टिमाइज़ करने के बारे में जानकारी के लिए, लाइब्रेरी के लेखकों के लिए ऑप्टिमाइज़ेशन लेख पढ़ें.
RuntimeInvisibleParameterAnnotations यह एट्रिब्यूट ऐसे एनोटेशन सेव करता है जो किसी तरीके के पैरामीटर पर रनटाइम में रिफ़्लेक्शन के साथ नहीं दिखते.

ऐप्लिकेशन डेवलपर को इस एट्रिब्यूट को नहीं रखना चाहिए. लाइब्रेरी के लेखकों के लिए, यह एट्रिब्यूट उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े नियमों में काम का नहीं है. हालांकि, लाइब्रेरी बनाते समय इसका इस्तेमाल अक्सर किया जाता है. लाइब्रेरी को ऑप्टिमाइज़ करने के बारे में जानकारी के लिए, लाइब्रेरी के लेखकों के लिए ऑप्टिमाइज़ेशन लेख पढ़ें.
RuntimeInvisibleTypeAnnotations यह एट्रिब्यूट, एनोटेशन सेव करता है. ये एनोटेशन, सिर्फ़ टाइप के इस्तेमाल पर लागू होते हैं, न कि सिर्फ़ एलान पर. यह एट्रिब्यूट, रनटाइम में नहीं दिखता.

ऐप्लिकेशन डेवलपर को इस एट्रिब्यूट को नहीं रखना चाहिए. लाइब्रेरी के लेखकों के लिए, यह एट्रिब्यूट उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े नियमों में काम का नहीं है. हालांकि, लाइब्रेरी बनाते समय इसका इस्तेमाल अक्सर किया जाता है. लाइब्रेरी को ऑप्टिमाइज़ करने के बारे में जानकारी के लिए, लाइब्रेरी के लेखकों के लिए ऑप्टिमाइज़ेशन लेख पढ़ें.