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