लाइब्रेरी के लेखकों के लिए ऑप्टिमाइज़ेशन

लाइब्रेरी के लेखक के तौर पर, आपको यह पक्का करना होगा कि ऐप्लिकेशन डेवलपर, आपकी लाइब्रेरी को आसानी से अपने ऐप्लिकेशन में शामिल कर सकें. साथ ही, यह भी पक्का करना होगा कि इससे उपयोगकर्ताओं को बेहतर अनुभव मिले. इसका मतलब है कि आपकी लाइब्रेरी, Android ऑप्टिमाइज़ेशन (R8) के साथ काम करनी चाहिए. इसके लिए, डेवलपर को कोई अतिरिक्त सेटअप करने की ज़रूरत नहीं होनी चाहिए. इसके अलावा, यह भी बताया जाना चाहिए कि लाइब्रेरी, Android पर इस्तेमाल करने के लिए सही नहीं है. यह ज़रूरी है कि Android पर इस्तेमाल की जाने वाली लाइब्रेरी, ऐप्लिकेशन के ज़रूरी ऑप्टिमाइज़ेशन को न रोकें. साथ ही, ऑप्टिमाइज़ेशन से जुड़ी अन्य ज़रूरी शर्तों का पालन करें.

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

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

डेटा बनाए रखने के नियमों के टाइप के बारे में जानकारी

लाइब्रेरी में दो तरह के कीप रूल हो सकते हैं:

  • उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े कीप नियमों में ऐसे नियम होने चाहिए जिनसे लाइब्रेरी में मौजूद सभी आइटम सुरक्षित रहें. अगर कोई लाइब्रेरी, अपने कोड या क्लाइंट ऐप्लिकेशन से तय किए गए कोड को कॉल करने के लिए रिफ़्लेक्शन या JNI का इस्तेमाल करती है, तो इन नियमों में यह जानकारी होनी चाहिए कि किस कोड को सुरक्षित रखना है. लाइब्रेरी में, उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े कीप नियमों को पैकेज किया जाना चाहिए. ये नियम, ऐप्लिकेशन के डेटा को सुरक्षित रखने से जुड़े कीप नियमों के फ़ॉर्मैट में ही होने चाहिए. ये नियम, लाइब्रेरी आर्टफ़ैक्ट (AAR या JAR) में बंडल किए जाते हैं. साथ ही, लाइब्रेरी का इस्तेमाल करते समय, Android ऐप्लिकेशन को ऑप्टिमाइज़ करने के दौरान इनका इस्तेमाल अपने-आप होता है. इन नियमों को उस फ़ाइल में सेव किया जाता है जिसे आपकी build.gradle.kts (या build.gradle) फ़ाइल में consumerProguardFiles प्रॉपर्टी के साथ तय किया गया है. ज़्यादा जानने के लिए, अन्य सुझाव लेख पढ़ें.
  • लाइब्रेरी बनाने से जुड़े कीप नियमों को तब लागू किया जाता है, जब आपकी लाइब्रेरी बनाई जाती है. इनकी ज़रूरत सिर्फ़ तब होती है, जब आपको लाइब्रेरी को बिल्ड टाइम पर आंशिक रूप से ऑप्टिमाइज़ करना हो. उन्हें लाइब्रेरी के सार्वजनिक एपीआई को हटाने से रोकना होगा. ऐसा न करने पर, सार्वजनिक एपीआई लाइब्रेरी के डिस्ट्रिब्यूशन में मौजूद नहीं होगा. इसका मतलब है कि ऐप्लिकेशन डेवलपर, लाइब्रेरी का इस्तेमाल नहीं कर पाएंगे. इन नियमों को उस फ़ाइल में सेव किया जाता है जिसे आपकी build.gradle.kts (या build.gradle) फ़ाइल में proguardFiles प्रॉपर्टी के साथ स्पेसिफ़ाई किया गया है. ज़्यादा जानने के लिए, AAR लाइब्रेरी के बिल्ड को ऑप्टिमाइज़ करना लेख पढ़ें.

ऑप्टिमाइज़ेशन से जुड़ी ज़रूरी शर्तें और दिशा-निर्देश

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

ऑप्टिमाइज़ेशन से जुड़ी ज़रूरी शर्तों का पालन करना

लाइब्रेरी के ठीक से काम न करने की वजह से, ऐप्लिकेशन का साइज़ बढ़ जाता है, मेमोरी का इस्तेमाल ज़्यादा होता है, ऐप्लिकेशन धीरे-धीरे शुरू होता है, और एएनआर (ऐप्लिकेशन काम नहीं कर रहा है) होती हैं. लाइब्रेरी को इन ज़रूरी शर्तों का उल्लंघन करने से बचना चाहिए. ऐसा न करने पर, ऐप्लिकेशन की क्वालिटी और उपयोगकर्ता अनुभव पर बुरा असर पड़ सकता है.

  • ब्रॉड या पैकेज-वाइड कीप नियम शामिल न हों: आपकी लाइब्रेरी में ब्रॉड कीप नियम शामिल नहीं होने चाहिए. ये ऐसे नियम होते हैं जो आपकी लाइब्रेरी या किसी दूसरी लाइब्रेरी में मौजूद ज़्यादातर कोड को सुरक्षित रखते हैं. डेटा को लंबे समय तक सेव रखने के लिए बनाए गए नियमों से, कुछ समय के लिए क्रैश की समस्या हल हो सकती है. हालांकि, इससे आपकी लाइब्रेरी का इस्तेमाल करने वाले सभी ऐप्लिकेशन का साइज़ बढ़ जाता है.

    अपनी लाइब्रेरी या अन्य रेफ़र की गई लाइब्रेरी में मौजूद पैकेज के लिए, पैकेज-वाइड कीप के नियम (जैसे कि -keep class com.mylibrary.** {*; }) शामिल न करें. इस तरह के नियमों की वजह से, आपकी लाइब्रेरी का इस्तेमाल करने वाले सभी ऐप्लिकेशन में इन पैकेज के लिए ऑप्टिमाइज़ेशन सीमित हो जाता है.

  • कोई भी आपत्तिजनक ग्लोबल नियम नहीं होना चाहिए: -dontobfuscate या -allowaccessmodification जैसे ग्लोबल विकल्पों का इस्तेमाल कभी न करें.

  • जब हो सके, तब रिफ़्लेक्शन के बजाय कोड जनरेशन का इस्तेमाल करें: जब हो सके, तब रिफ़्लेक्शन के बजाय कोड जनरेशन (codegen) का इस्तेमाल करें. प्रोग्रामिंग करते समय, बॉयलरप्लेट कोड से बचने के लिए कोड जनरेशन और रिफ़्लेक्शन, दोनों सामान्य तरीके हैं. हालांकि, कोड जनरेशन, R8 जैसे ऐप्लिकेशन ऑप्टिमाइज़र के साथ ज़्यादा काम करता है.

    कोड जनरेशन की सुविधा की मदद से, कोड का विश्लेषण किया जाता है और उसे बिल्ड प्रोसेस के दौरान बदला जाता है. कंपाइल टाइम के बाद कोई बड़ा बदलाव नहीं किया जाता. इसलिए, ऑप्टिमाइज़र को पता होता है कि आखिर में किस कोड की ज़रूरत है और किस कोड को सुरक्षित तरीके से हटाया जा सकता है.

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

    आजकल की कई लाइब्रेरी, रिफ़्लेक्शन के बजाय कोडजन का इस्तेमाल करती हैं. Room, Hilt, और कई अन्य लाइब्रेरी के लिए इस्तेमाल किए जाने वाले कॉमन एंट्रीपॉइंट के लिए, KSP देखें.

  • R8 फ़ुल मोड के साथ काम करना: R8 फ़ुल मोड चालू होने पर, आपकी लाइब्रेरी क्रैश नहीं होनी चाहिए. R8 का इस्तेमाल करने के लिए, R8 के फ़ुल मोड का इस्तेमाल करने का सुझाव दिया जाता है. साथ ही, AGP 8.0 के बाद से यह डिफ़ॉल्ट मोड है. AGP 8.0 को 2023 में स्टेबल किया गया था. अगर R8 की वजह से आपकी लाइब्रेरी क्रैश हो जाती है, तो समस्या को ठीक करने के लिए, आपको रिफ़्लेक्शन या JNI एंट्री पॉइंट की पहचान करनी होगी. इसके बाद, पूरे पैकेज को सेव करने के बजाय, टारगेट किया गया नियम जोड़ना होगा.

कुछ और सुझाव

ऑप्टिमाइज़ेशन से जुड़ी ज़रूरी शर्तों के अलावा, यहां कुछ अन्य सुझाव दिए गए हैं.

  • अपनी लाइब्रेरी के उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े कीप नियमों की फ़ाइल में -repackageclasses का इस्तेमाल न करें. हालांकि, अपनी लाइब्रेरी के बिल्ड को ऑप्टिमाइज़ करने के लिए, -repackageclasses का इस्तेमाल किया जा सकता है. इसके लिए, लाइब्रेरी के बिल्ड कीप रूल्स फ़ाइल में <your.library.package>.internal जैसे इंटरनल पैकेज का नाम डालें. इससे, ऑप्टिमाइज़ न किए गए ऐप्लिकेशन में आपकी लाइब्रेरी की परफ़ॉर्मेंस बेहतर हो सकती है. हालांकि, आम तौर पर इसकी ज़रूरत नहीं होती, क्योंकि ऐप्लिकेशन को भी ऑप्टिमाइज़ किया जाना चाहिए.
  • अपनी लाइब्रेरी के लिए ज़रूरी एट्रिब्यूट का एलान, लाइब्रेरी के कीप नियमों वाली फ़ाइलों में करें. भले ही, proguard-android-optimize.txt में तय किए गए एट्रिब्यूट के साथ ओवरलैप हो रहा हो.
  • अगर आपको अपनी लाइब्रेरी के डिस्ट्रिब्यूशन में इन एट्रिब्यूट की ज़रूरत है, तो इन्हें अपनी लाइब्रेरी की बिल्ड कीप रूल्स फ़ाइल में बनाए रखें. साथ ही, इन्हें अपनी लाइब्रेरी की कंज्यूमर कीप रूल्स फ़ाइल में रखें:
    • AnnotationDefault
    • EnclosingMethod
    • Exceptions
    • InnerClasses
    • RuntimeInvisibleAnnotations
    • RuntimeInvisibleParameterAnnotations
    • RuntimeInvisibleTypeAnnotations
    • RuntimeVisibleAnnotations
    • RuntimeVisibleParameterAnnotations
    • RuntimeVisibleTypeAnnotations
    • Signature
  • अगर लाइब्रेरी तैयार करने वाले डेवलपर, रनटाइम में एनोटेशन का इस्तेमाल करते हैं, तो उन्हें उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े नियमों में RuntimeVisibleAnnotations एट्रिब्यूट को शामिल करना चाहिए.
  • लाइब्रेरी तैयार करने वाले डेवलपर को उपभोक्ता के लिए डेटा सुरक्षित रखने वाले कीप नियमों में, इन ग्लोबल विकल्पों का इस्तेमाल नहीं करना चाहिए:
    • -include
    • -basedirectory
    • -injars
    • -outjars
    • -libraryjars
    • -repackageclasses
    • -flattenpackagehierarchy
    • -allowaccessmodification
    • -renamesourcefileattribute
    • -ignorewarnings
    • -addconfigurationdebugging
    • -printconfiguration
    • -printmapping
    • -printusage
    • -printseeds
    • -applymapping
    • -obfuscationdictionary
    • -classobfuscationdictionary
    • -packageobfuscationdictionary

जब इमेज में रिफ़्लेक्शन सही हो

अगर आपको रिफ़्लेक्शन का इस्तेमाल करना है, तो आपको सिर्फ़ इनमें से किसी एक में रिफ़्लेक्ट करना चाहिए:

  • टारगेट किए गए खास टाइप (खास इंटरफ़ेस लागू करने वाले या सबक्लास)
  • किसी खास रनटाइम एनोटेशन का इस्तेमाल करने वाला कोड

इस तरह से रिफ़्लेक्शन का इस्तेमाल करने से, रनटाइम की लागत कम हो जाती है. साथ ही, उपयोगकर्ताओं के लिए तय किए गए डेटा को सुरक्षित रखने के नियमों को लिखा जा सकता है.

इस तरह की खास और टारगेट की गई रिफ़्लेक्शन, एक ऐसा पैटर्न है जो आपको Android फ़्रेमवर्क (उदाहरण के लिए, सिस्टम रिसॉर्स लोड करने के दौरान) और AndroidX लाइब्रेरी (उदाहरण के लिए, WorkManager ListenableWorkers या RoomDatabases बनाते समय) दोनों में दिख सकता है. इसके उलट, Gson की ओपन एंडेड रिफ़्लेक्शन, Android ऐप्लिकेशन में इस्तेमाल करने के लिए सही नहीं है.

सामान्य भ्रांतियां

कुछ आम गलतफ़हमियों की वजह से, R8 को गलत तरीके से कॉन्फ़िगर किया जा सकता है. इनमें ये शामिल हैं:

  • R8 के ऑप्टिमाइज़ेशन के बारे में गलत जानकारी होना: आम तौर पर यह माना जाता है कि R8 के ऑप्टिमाइज़ेशन सिर्फ़ कोड को छिपाने तक सीमित होते हैं. हालांकि, ऐसा नहीं है. इसमें कोड को छोटा करना और लॉजिकल ऑप्टिमाइज़ेशन भी शामिल होते हैं. इसके लिए, मेथड इनलाइनिंग और क्लास मर्जिंग तकनीकों का इस्तेमाल किया जाता है. ज़्यादा जानकारी के लिए, R8 ऑप्टिमाइज़ेशन के बारे में खास जानकारी देखें.

  • ऑब्फ़स्केट की गई लाइब्रेरी के ऑप्टिमाइज़ेशन को बायपास करना: एक सामान्य गड़बड़ी यह है कि लाइब्रेरी को ऑप्टिमाइज़ेशन से हटा दिया जाता है. ऐसा इसलिए होता है, क्योंकि लाइब्रेरी को AAR (Android Archive) या JAR (Java Archive) में कंपाइल करते समय ऑप्टिमाइज़ या ऑब्फ़स्केट किया गया था. लाइब्रेरी बनाने के दौरान ऑप्टिमाइज़ेशन सीमित होते हैं. साथ ही, आपके ऐप्लिकेशन को कीप नियम में लाइब्रेरी को शामिल करके, लाइब्रेरी के ऑप्टिमाइज़ेशन को बंद नहीं करना चाहिए. ज़्यादा जानकारी के लिए, R8 ऑप्टिमाइज़ेशन के बारे में खास जानकारी देखें.

  • -keep विकल्प को सही तरीके से न समझना -keep नियम की वजह से, R8 अपने किसी भी ऑप्टिमाइज़ेशन पास को नहीं चला पाता. ज़्यादा जानकारी के लिए, सही कीप ऑप्शन चुनना लेख पढ़ें.

उपयोगकर्ता के डेटा को सुरक्षित रखने से जुड़े नियम की क्वालिटी की पुष्टि करना

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

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

नियम पैकेजिंग को कॉन्फ़िगर करना

यह पक्का करने के लिए कि उपभोक्ता डेटा को सुरक्षित रखने से जुड़े नियमों को सही तरीके से लागू किया गया है, आपको उन्हें अपनी लाइब्रेरी के फ़ॉर्मैट के हिसाब से सही तरीके से पैकेज करना होगा.

एएआर लाइब्रेरी

किसी एएआर लाइब्रेरी के लिए उपभोक्ता नियम जोड़ने के लिए, Android लाइब्रेरी मॉड्यूल की बिल्ड स्क्रिप्ट में consumerProguardFiles विकल्प का इस्तेमाल करें. ज़्यादा जानकारी के लिए, लाइब्रेरी मॉड्यूल बनाने के बारे में दिशा-निर्देश देखें.

Kotlin

android {
    defaultConfig {
        consumerProguardFiles("consumer-proguard-rules.pro")
    }
    ...
}

Groovy

android {
    defaultConfig {
        consumerProguardFiles 'consumer-proguard-rules.pro'
    }
    ...
}

ज़ार लाइब्रेरी

अगर आपको अपनी Kotlin या Java लाइब्रेरी के साथ नियमों को बंडल करना है, तो अपनी नियमों वाली फ़ाइल को फ़ाइनल JAR की META-INF/proguard/ डायरेक्ट्री में रखें. फ़ाइल का नाम कुछ भी हो सकता है. उदाहरण के लिए, अगर आपका कोड <libraryroot>/src/main/kotlin में है, तो उपभोक्ता नियमों वाली फ़ाइल को <libraryroot>/src/main/resources/META-INF/proguard/consumer-proguard-rules.pro पर रखें. इसके बाद, नियमों को आपके आउटपुट JAR में सही जगह पर बंडल कर दिया जाएगा.

पुष्टि करें कि फ़ाइनल JAR बंडल में नियम सही तरीके से लागू किए गए हैं. इसके लिए, यह देखें कि नियम META-INF/proguard डायरेक्ट्री में मौजूद हैं या नहीं.

AAR लाइब्रेरी के बिल्ड को ऑप्टिमाइज़ करना (ऐडवांस)

आम तौर पर, आपको लाइब्रेरी बिल्ड को सीधे तौर पर ऑप्टिमाइज़ करने की ज़रूरत नहीं होती, क्योंकि लाइब्रेरी बिल्ड के समय किए जा सकने वाले ऑप्टिमाइज़ेशन बहुत कम होते हैं. लाइब्रेरी डेवलपर के तौर पर, आपको ऑप्टिमाइज़ेशन के कई चरणों के बारे में जानकारी होनी चाहिए. साथ ही, लाइब्रेरी और ऐप्लिकेशन के बिल्ड प्रोसेस में लगने वाले समय, दोनों के दौरान लाइब्रेरी के व्यवहार के बारे में पता होना चाहिए. इसके बाद ही, आपको लाइब्रेरी को ऑप्टिमाइज़ करना चाहिए.

अगर आपको अब भी लाइब्रेरी को बिल्ड टाइम पर ऑप्टिमाइज़ करना है, तो Android Gradle Plugin की मदद से ऐसा किया जा सकता है.

Kotlin

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
        configureEach {
            consumerProguardFiles("consumer-rules.pro")
        }
    }
}

Groovy

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles
                getDefaultProguardFile('proguard-android-optimize.txt'),
                'proguard-rules.pro'
        }
        configureEach {
            consumerProguardFiles "consumer-rules.pro"
        }
    }
}

ध्यान दें कि proguardFiles का व्यवहार, consumerProguardFiles से काफ़ी अलग होता है:

  • proguardFiles का इस्तेमाल, बिल्ड प्रोसेस में लगने वाले समय के दौरान किया जाता है. अक्सर इनका इस्तेमाल getDefaultProguardFile("proguard-android-optimize.txt") के साथ किया जाता है. इससे यह तय किया जाता है कि लाइब्रेरी बनाने के दौरान, आपकी लाइब्रेरी का कौनसा हिस्सा सुरक्षित रखा जाना चाहिए. कम से कम, यह आपका सार्वजनिक एपीआई है.
  • इसके उलट, consumerProguardFiles को लाइब्रेरी में पैकेज किया जाता है, ताकि बाद में ऑप्टिमाइज़ेशन पर असर पड़े. ऐसा तब होता है, जब आपकी लाइब्रेरी का इस्तेमाल करने वाला ऐप्लिकेशन बनाया जाता है.

उदाहरण के लिए, अगर आपकी लाइब्रेरी इंटरनल क्लास बनाने के लिए रिफ़्लेक्शन का इस्तेमाल करती है, तो आपको proguardFiles और consumerProguardFiles, दोनों में कीप रूल तय करने पड़ सकते हैं.

अगर आपने अपनी लाइब्रेरी के बिल्ड में -repackageclasses का इस्तेमाल किया है, तो क्लास को अपनी लाइब्रेरी के पैकेज के अंदर मौजूद सब-पैकेज में फिर से पैकेज करें. उदाहरण के लिए, -repackageclasses 'internal' के बजाय -repackageclasses 'com.example.mylibrary.internal' का इस्तेमाल करें.

Compose यूज़र इंटरफ़ेस (यूआई) की परफ़ॉर्मेंस को ऑप्टिमाइज़ करना

अगर आपकी लाइब्रेरी में Compose UI कॉम्पोनेंट शामिल हैं, तो R8 की मदद से बाइनरी को छोटा करने (जैसा कि पहले बताया गया है) और रीकंपोज़िशन की परफ़ॉर्मेंस, दोनों के लिए ऑप्टिमाइज़ करें:

  • स्थिर कंपोज़ेबल डिज़ाइन करें: अगर इनपुट में कोई बदलाव नहीं हुआ है, तो कंपाइलर को आपके कंपोज़ेबल को सुरक्षित तरीके से स्किप करने की अनुमति दें. इसके लिए, अपने डेटा मॉडल और लाइब्रेरी कॉन्फ़िगरेशन को इस तरह से स्ट्रक्चर करें कि वे स्थिरता के नियमों का पालन करें. ज़्यादा जानकारी के लिए, Compose में स्थिरता देखें.
  • कंपाइलर मेट्रिक की समीक्षा करें: Compose कंपाइलर मेट्रिक का इस्तेमाल करके पुष्टि करें कि आपकी लाइब्रेरी के एंट्री पॉइंट, रीस्टार्ट किए जा सकते हैं और उन्हें स्किप किया जा सकता है. इससे, उपभोक्ता ऐप्लिकेशन के लिए रीकंपोज़िशन ओवरहेड कम हो जाता है. ज़्यादा जानकारी के लिए, ऐप्लिकेशन के क्रैश होने की समस्याओं का पता लगाना लेख पढ़ें.

R8 के अलग-अलग वर्शन के साथ काम करना (ऐडवांस)

R8 के किसी खास वर्शन को टारगेट करने के लिए, नियमों को अपनी ज़रूरत के हिसाब से बनाया जा सकता है. इससे आपकी लाइब्रेरी, R8 के नए वर्शन का इस्तेमाल करने वाले प्रोजेक्ट में बेहतर तरीके से काम कर पाती है. साथ ही, R8 के पुराने वर्शन का इस्तेमाल करने वाले प्रोजेक्ट में मौजूदा नियमों का इस्तेमाल जारी रखा जा सकता है.

टारगेट किए गए R8 नियमों को तय करने के लिए, आपको उन्हें AAR के META-INF/com.android.tools डायरेक्ट्री में मौजूद classes.jar या JAR की META-INF/com.android.tools डायरेक्ट्री में शामिल करना होगा.

In an AAR library:
    proguard.txt (legacy location, the file name must be "proguard.txt")
    classes.jar
    └── META-INF
        └── com.android.tools (location of targeted R8 rules)
            ├── r8-from-<X>-upto-<Y>/<R8-rule-files>
            └── ... (more directories with the same name format)

In a JAR library:
    META-INF
    ├── proguard/<ProGuard-rule-files> (legacy location)
    └── com.android.tools (location of targeted R8 rules)
        ├── r8-from-<X>-upto-<Y>/<R8-rule-files>
        └── ... (more directories with the same name format)

META-INF/com.android.tools डायरेक्ट्री में, कई सबडायरेक्ट्री हो सकती हैं. इनके नाम r8-from-<X>-upto-<Y> के फ़ॉर्मैट में होते हैं. इससे यह पता चलता है कि नियम, R8 के किन वर्शन के लिए लिखे गए हैं. हर सबडायरेक्ट्री में, R8 के नियमों वाली एक या उससे ज़्यादा फ़ाइलें हो सकती हैं. इनके नाम और एक्सटेंशन कुछ भी हो सकते हैं.

ध्यान दें कि -from-<X> और -upto-<Y> हिस्से ज़रूरी नहीं हैं. <Y> वर्शन एक्सक्लूसिव है. साथ ही, वर्शन की रेंज आम तौर पर लगातार होती है, लेकिन यह ओवरलैप भी हो सकती है.

उदाहरण के लिए, r8, r8-upto-8.0.0, r8-from-8.0.0-upto-8.2.0, और r8-from-8.2.0, डायरेक्ट्री के नाम हैं. ये टारगेट की गई R8 की नियमों के सेट को दिखाते हैं. r8 डायरेक्ट्री में मौजूद नियमों का इस्तेमाल, R8 के किसी भी वर्शन के लिए किया जा सकता है. r8-from-8.0.0-upto-8.2.0 डायरेक्ट्री में मौजूद नियमों का इस्तेमाल, R8 के वर्शन 8.0.0 से लेकर 8.2.0 तक किया जा सकता है. हालांकि, 8.2.0 शामिल नहीं है.

Android Gradle प्लगिन, इस जानकारी का इस्तेमाल करके उन सभी नियमों को चुनता है जिनका इस्तेमाल R8 के मौजूदा वर्शन के साथ किया जा सकता है. अगर कोई लाइब्रेरी, टारगेट किए गए R8 नियमों के बारे में नहीं बताती है, तो Android Gradle प्लगिन, लेगसी लोकेशन (एएआर के लिए proguard.txt या JAR के लिए META-INF/proguard/<ProGuard-rule-files>) से नियमों को चुनेगा.