लाइब्रेरी के लेखक के तौर पर, आपको यह पक्का करना होगा कि ऐप्लिकेशन डेवलपर, आपकी लाइब्रेरी को आसानी से अपने ऐप्लिकेशन में शामिल कर सकें. साथ ही, यह भी पक्का करना होगा कि इससे उपयोगकर्ताओं को बेहतर अनुभव मिले. इसका मतलब है कि आपकी लाइब्रेरी, डेवलपर के किसी अतिरिक्त सेटअप के बिना Android ऑप्टिमाइज़ेशन (R8) के साथ काम करनी चाहिए. इसके अलावा, यह भी बताया जाना चाहिए कि लाइब्रेरी, Android पर इस्तेमाल करने के लिए सही नहीं है. यह ज़रूरी है कि Android पर इस्तेमाल की जाने वाली लाइब्रेरी, ऐप्लिकेशन के ज़रूरी ऑप्टिमाइज़ेशन को न रोकें. साथ ही, ऑप्टिमाइज़ेशन से जुड़ी अन्य ज़रूरी शर्तों का पालन करें.
यह दस्तावेज़, पब्लिश की गई लाइब्रेरी के डेवलपर के लिए है. हालांकि, यह बड़े और मॉड्यूलर ऐप्लिकेशन में इंटरनल लाइब्रेरी मॉड्यूल के डेवलपर के लिए भी काम का हो सकता है.
अगर आप ऐप्लिकेशन डेवलपर हैं और आपको अपने Android ऐप्लिकेशन को ऑप्टिमाइज़ करने के बारे में जानना है, तो ऐप्लिकेशन ऑप्टिमाइज़ेशन की सुविधा चालू करना लेख पढ़ें. कौनसी लाइब्रेरी का इस्तेमाल करना सही है, इस बारे में जानने के लिए लाइब्रेरी का सोच-समझकर चुनाव करना लेख पढ़ें.
डेटा बनाए रखने के नियमों के टाइप के बारे में जानकारी
लाइब्रेरी में दो तरह के डेटा को सुरक्षित रखने के नियम लागू किए जा सकते हैं:
- उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े कीप नियमों में, ऐसे नियम शामिल होने चाहिए जो लाइब्रेरी में मौजूद हर चीज़ को सुरक्षित रखें. अगर कोई लाइब्रेरी, अपने कोड या क्लाइंट ऐप्लिकेशन से तय किए गए कोड को कॉल करने के लिए रिफ़्लेक्शन या JNI का इस्तेमाल करती है, तो इन नियमों में यह जानकारी होनी चाहिए कि किस कोड को बनाए रखना है. लाइब्रेरी में, उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े कीप नियम शामिल होने चाहिए. ये नियम, ऐप्लिकेशन के कीप नियमों के फ़ॉर्मैट का ही इस्तेमाल करते हैं. ये नियम, लाइब्रेरी के आर्टफ़ैक्ट (AAR या JAR) में बंडल किए जाते हैं. साथ ही, लाइब्रेरी का इस्तेमाल करते समय, Android ऐप्लिकेशन को ऑप्टिमाइज़ करने के दौरान इनका इस्तेमाल अपने-आप होता है. इन नियमों को आपकी
build.gradle.kts(याbuild.gradle) फ़ाइल में,consumerProguardFilesप्रॉपर्टी के साथ बताई गई फ़ाइल में सेव किया जाता है. ज़्यादा जानने के लिए, उपयोगकर्ता के डेटा को सुरक्षित रखने के नियम लिखना लेख पढ़ें. - लाइब्रेरी बनाने के दौरान डेटा को सुरक्षित रखने से जुड़े नियम लागू होते हैं. इनकी ज़रूरत सिर्फ़ तब होती है, जब आपको बिल्ड टाइम पर अपनी लाइब्रेरी को आंशिक रूप से ऑप्टिमाइज़ करना हो. उन्हें लाइब्रेरी के सार्वजनिक एपीआई को हटाए जाने से रोकना होगा. ऐसा न करने पर, लाइब्रेरी डिस्ट्रिब्यूशन में सार्वजनिक एपीआई मौजूद नहीं होगा. इसका मतलब है कि ऐप्लिकेशन डेवलपर, लाइब्रेरी का इस्तेमाल नहीं कर पाएंगे. इन नियमों को उस फ़ाइल में सेव किया जाता है जिसे आपकी
build.gradle.kts(याbuild.gradle) फ़ाइल मेंproguardFilesप्रॉपर्टी के साथ स्पेसिफ़ाई किया गया है. ज़्यादा जानने के लिए, एएआर लाइब्रेरी बिल्ड को ऑप्टिमाइज़ करना लेख पढ़ें.
ऑप्टिमाइज़ेशन से जुड़ी ज़रूरी शर्तें और दिशा-निर्देश
लाइब्रेरी में R8 कॉन्फ़िगरेशन का, ऐप्लिकेशन के फ़ाइनल बाइनरी साइज़ और परफ़ॉर्मेंस पर असर पड़ता है. कीप नियम के सबसे सही तरीकों के अलावा, लाइब्रेरी तैयार करने वाले डेवलपर को कुछ खास ज़रूरी शर्तों का पालन करना होगा. साथ ही, उन्हें अन्य दिशा-निर्देशों का भी ध्यान रखना होगा.
ऑप्टिमाइज़ेशन से जुड़ी ज़रूरी शर्तों का पालन करना
लाइब्रेरी में मौजूद गड़बड़ियों की वजह से, ऐप्लिकेशन का साइज़ बढ़ जाता है, मेमोरी बर्बाद होती है, ऐप्लिकेशन धीरे-धीरे शुरू होता है, और ANR (ऐप्लिकेशन काम नहीं कर रहा है, जैसी गड़बड़ियां) जैसी समस्याएं आती हैं. लाइब्रेरी को इन ज़रूरी शर्तों का उल्लंघन करने से बचना चाहिए. ऐसा न करने पर, ऐप्लिकेशन की क्वालिटी और उपयोगकर्ता अनुभव पर बुरा असर पड़ सकता है.
डेटा सुरक्षित रखने के लिए, ब्रॉड या पैकेज-वाइड कीप नियम न हों: आपकी लाइब्रेरी में, डेटा सुरक्षित रखने के लिए ऐसे ब्रॉड कीप नियम शामिल नहीं होने चाहिए जो आपकी लाइब्रेरी या किसी दूसरी लाइब्रेरी में मौजूद ज़्यादातर कोड को सुरक्षित रखते हों. ब्रॉड कीप रूल से, ऐप्लिकेशन क्रैश होने की समस्या को कुछ समय के लिए ठीक किया जा सकता है. हालांकि, इनसे आपकी लाइब्रेरी का इस्तेमाल करने वाले सभी ऐप्लिकेशन का साइज़ बढ़ जाता है.
अपनी लाइब्रेरी या अन्य रेफ़र की गई लाइब्रेरी में मौजूद पैकेज के लिए, पैकेज-वाइड कीप के नियम (जैसे कि
-keep class com.mylibrary.** {*; }) शामिल न करें. ऐसे नियम, आपकी लाइब्रेरी का इस्तेमाल करने वाले सभी ऐप्लिकेशन में, इन पैकेज के ऑप्टिमाइज़ेशन को सीमित करते हैं.गलत ग्लोबल नियम न बनाएं:
-dontobfuscateया-allowaccessmodificationजैसे ग्लोबल विकल्पों का इस्तेमाल कभी न करें.जब भी संभव हो, रिफ़्लेक्शन के बजाय कोडजेन का इस्तेमाल करें: जब भी संभव हो, रिफ़्लेक्शन के बजाय कोड जनरेशन (कोडजेन) का इस्तेमाल करें. प्रोग्रामिंग करते समय, बॉयलरप्लेट कोड से बचने के लिए कोड जनरेशन और रिफ़्लेक्शन, दोनों सामान्य तरीके हैं. हालांकि, कोड जनरेशन, R8 जैसे ऐप्लिकेशन ऑप्टिमाइज़र के साथ ज़्यादा बेहतर तरीके से काम करता है.
कोड जनरेशन की मदद से, बिल्ड प्रोसेस के दौरान कोड का विश्लेषण किया जाता है और उसमें बदलाव किया जाता है. कंपाइल के समय के बाद कोई बड़ा बदलाव नहीं होता. इसलिए, ऑप्टिमाइज़र को पता होता है कि आखिर में किस कोड की ज़रूरत है और किसे सुरक्षित तरीके से हटाया जा सकता है.
रिफ़्लेक्शन की मदद से, कोड का विश्लेषण किया जाता है और उसे रनटाइम में बदला जाता है. कोड के एक्ज़ीक्यूट होने तक, उसे फ़ाइनल नहीं माना जाता. इसलिए, ऑप्टिमाइज़र को यह पता नहीं होता कि कौनसे कोड को सुरक्षित तरीके से हटाया जा सकता है. ऐसा हो सकता है कि यह उस कोड को हटा दे जिसका इस्तेमाल रनटाइम के दौरान, रिफ़्लेक्शन के ज़रिए डाइनैमिक तौर पर किया जाता है. इससे उपयोगकर्ताओं के लिए ऐप्लिकेशन क्रैश हो जाता है.
आजकल की कई लाइब्रेरी, रिफ़्लेक्शन के बजाय कोडजन का इस्तेमाल करती हैं. Room, Hilt, और कई अन्य लाइब्रेरी के लिए इस्तेमाल किए जाने वाले सामान्य एंट्रीपॉइंट के लिए, KSP देखें.
R8 फ़ुल मोड के साथ काम करना: R8 फ़ुल मोड चालू होने पर, आपकी लाइब्रेरी क्रैश नहीं होनी चाहिए. R8 का इस्तेमाल करने के लिए, R8 का फ़ुल मोड इस्तेमाल करने का सुझाव दिया जाता है. यह AGP 8.0 के बाद से डिफ़ॉल्ट रूप से सेट होता है. इसे 2023 में स्टेबल बनाया गया था. अगर R8 की वजह से आपकी लाइब्रेरी क्रैश हो जाती है, तो इसका समाधान यह है कि रिफ़्लेक्शन या जेएनआई एंट्री पॉइंट की पहचान करें और टारगेट किया गया नियम जोड़ें. पूरे पैकेज को बनाए रखने की ज़रूरत नहीं है.
कुछ और सुझाव
ऑप्टिमाइज़ेशन की ज़रूरी शर्तों के अलावा, यहां कुछ और सुझाव दिए गए हैं.
- अपनी लाइब्रेरी के उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े कीप नियमों की फ़ाइल में,
-repackageclassesका इस्तेमाल न करें. हालांकि, लाइब्रेरी बिल्ड को ऑप्टिमाइज़ करने के लिए, लाइब्रेरी की बिल्ड कीप रूल्स फ़ाइल में,-repackageclassesका इस्तेमाल किसी इंटरनल पैकेज के नाम के साथ किया जा सकता है. जैसे,<your.library.package>.internal. इससे, ऑप्टिमाइज़ नहीं किए गए ऐप्लिकेशन में आपकी लाइब्रेरी की परफ़ॉर्मेंस बेहतर हो सकती है. हालांकि, आम तौर पर इसकी ज़रूरत नहीं होती, क्योंकि ऐप्लिकेशन भी ऑप्टिमाइज़ होने चाहिए. - अपनी लाइब्रेरी के लिए ज़रूरी सभी एट्रिब्यूट को लाइब्रेरी की कीप रूल फ़ाइलों में शामिल करें. भले ही, वे एट्रिब्यूट
proguard-android-optimize.txtमें पहले से मौजूद हों. - अगर आपको अपनी लाइब्रेरी के डिस्ट्रिब्यूशन में इन एट्रिब्यूट की ज़रूरत है, तो इन्हें अपनी लाइब्रेरी की बिल्ड कीप रूल्स फ़ाइल में बनाए रखें. साथ ही, इन्हें अपनी लाइब्रेरी की उपभोक्ता कीप रूल्स फ़ाइल में नहीं बनाए रखें:
AnnotationDefaultEnclosingMethodExceptionsInnerClassesRuntimeInvisibleAnnotationsRuntimeInvisibleParameterAnnotationsRuntimeInvisibleTypeAnnotationsRuntimeVisibleAnnotationsRuntimeVisibleParameterAnnotationsRuntimeVisibleTypeAnnotationsSignature
- अगर रनटाइम में एनोटेशन का इस्तेमाल किया जाता है, तो लाइब्रेरी तैयार करने वाले डेवलपर को उपभोक्ता के डेटा को सुरक्षित रखने से जुड़े कीप नियमों में
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 ऑप्टिमाइज़ेशन की खास जानकारी देखें.
ऑब्फ़स्केट की गई लाइब्रेरी के ऑप्टिमाइज़ेशन को बायपास करना: एक सामान्य गड़बड़ी यह है कि ऑप्टिमाइज़ेशन से किसी लाइब्रेरी को हटा दिया जाता है. ऐसा इसलिए होता है, क्योंकि लाइब्रेरी को एएआर (Android संग्रह) या जेएआर (Java संग्रह) में कंपाइल करते समय, ऑप्टिमाइज़ या ऑब्फ़स्केट किया गया था. लाइब्रेरी बिल्ड प्रोसेस के दौरान, ऑप्टिमाइज़ेशन सीमित होते हैं. साथ ही, आपके ऐप्लिकेशन को लाइब्रेरी के ऑप्टिमाइज़ेशन को बंद नहीं करना चाहिए. इसके लिए, उसे कीप नियम में शामिल करना चाहिए. ज़्यादा जानकारी के लिए, AAR लाइब्रेरी के बिल्ड को ऑप्टिमाइज़ करना लेख पढ़ें.
-keepविकल्प के बारे में गलत जानकारी-keepनियम, R8 को ऑप्टिमाइज़ेशन पास चलाने से रोकता है. ज़्यादा जानकारी के लिए, सही कीप ऑप्शन चुनना लेख पढ़ें.
उपभोक्ता के लिए, डेटा सेव रखने के नियम की क्वालिटी की पुष्टि करना
यह पुष्टि करने के लिए कि किसी ऐप्लिकेशन में एम्बेड किए जाने पर, आपकी लाइब्रेरी बहुत ज़्यादा कोड ऑप्टिमाइज़ेशन को नहीं रोकती है, लाइब्रेरी के सैंपल या इंटिग्रेशन टेस्ट ऐप्लिकेशन का इस्तेमाल करें. R8 को चालू करें और R8 Configuration Analyzer की मदद से, ऐप्लिकेशन के R8 कॉन्फ़िगरेशन की क्वालिटी की जांच करें.
अगर आपके उपभोक्ता नियम, आपकी लाइब्रेरी के कोड के बड़े हिस्सों पर ऑप्टिमाइज़ेशन को सीमित करते हैं, तो इसका मतलब है कि आपके उपभोक्ता नियमों में सुधार की ज़रूरत है. उपयोगकर्ता से जुड़े नियमों को सीमित करें. साथ ही, R8 की सुविधा चालू करके, ऐप्लिकेशन में अपनी लाइब्रेरी के उन पहलुओं की जांच करें जिन पर असर पड़ा है.
नियम की पैकेजिंग कॉन्फ़िगर करना
यह पक्का करने के लिए कि आपके उपभोक्ता के लिए बनाए गए नियम सही तरीके से लागू हों, आपको उन्हें अपनी लाइब्रेरी के फ़ॉर्मैट के हिसाब से सही तरीके से पैकेज करना होगा.
अगर अपनी लाइब्रेरी के रिफ़्लेक्शन और जेएनआई के इस्तेमाल के बारे में बताने के लिए, Jetpack Keep का इस्तेमाल किया जाता है, तो इसका Gradle प्लगिन, जनरेट किए गए नियमों को उपभोक्ता के लिए बनाए रखने के नियमों के तौर पर पैकेज कर सकता है.
एएआर लाइब्रेरी
किसी एएआर लाइब्रेरी के लिए उपभोक्ता नियम जोड़ने के लिए, Android लाइब्रेरी मॉड्यूल की बिल्ड स्क्रिप्ट में consumerProguardFiles विकल्प का इस्तेमाल करें. ज़्यादा जानकारी के लिए, लाइब्रेरी मॉड्यूल बनाने के बारे में हमारे दिशा-निर्देश देखें.
Kotlin
android {
defaultConfig {
consumerProguardFiles("consumer-proguard-rules.pro")
}
...
}
Groovy
android {
defaultConfig {
consumerProguardFiles 'consumer-proguard-rules.pro'
}
...
}
ज़ार लाइब्रेरी
अगर आपको नियमों को JAR के तौर पर शिप की जाने वाली 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 प्लगिन का इस्तेमाल करें.
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' का इस्तेमाल करें.
R8 के अलग-अलग वर्शन के साथ काम करता है (ऐडवांस)
R8 के खास वर्शन को टारगेट करने के लिए, नियमों में बदलाव किया जा सकता है. इससे आपकी लाइब्रेरी, R8 के नए वर्शन का इस्तेमाल करने वाले प्रोजेक्ट में बेहतर तरीके से काम कर पाती है. साथ ही, R8 के पुराने वर्शन वाले प्रोजेक्ट में मौजूदा नियमों का इस्तेमाल जारी रखा जा सकता है.
टारगेट किए गए R8 नियमों की जानकारी देने के लिए, आपको उन्हें एएआर के classes.jar में मौजूद META-INF/com.android.tools डायरेक्ट्री में या 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 या जेएआर के लिए META-INF/proguard/<ProGuard-rule-files>) से नियम चुनेगा.