इस पेज पर बताया गया है कि आप एक ही प्रोजेक्ट से अपने ऐप्लिकेशन के अलग-अलग वर्शन बनाने के लिए, बिल्ड वैरिएंट कैसे कॉन्फ़िगर कर सकते हैं. साथ ही, अपनी डिपेंडेंसी और साइनिंग कॉन्फ़िगरेशन को सही तरीके से मैनेज करने का तरीका भी बताया गया है.
हर बिल्ड वैरिएंट, आपके ऐप्लिकेशन के एक अलग वर्शन को दिखाता है, जिसे बनाया जा सकता है. उदाहरण के लिए, हो सकता है कि आप अपने ऐप्लिकेशन का एक ऐसा वर्शन बनाना चाहें जो कॉन्टेंट के सीमित सेट के साथ मुफ़्त हो और दूसरा ऐसा वर्शन हो जिसमें ज़्यादा कॉन्टेंट शामिल हो और पैसे चुकाकर डाउनलोड किया जा सके. आपके पास एपीआई लेवल या डिवाइस के अन्य वैरिएशन के आधार पर, अलग-अलग डिवाइसों को टारगेट करने वाले अपने ऐप्लिकेशन के अलग-अलग वर्शन बनाने का विकल्प भी होता है.
बिल्ड के वैरिएंट, Gradle को बनाने के लिए बने नियमों के खास सेट का इस्तेमाल करते हैं. इससे आपके बिल्ड टाइप और प्रॉडक्ट के फ़्लेवर में कॉन्फ़िगर की गई सेटिंग, कोड, और संसाधनों को जोड़ा जाता है. बिल्ड के वैरिएंट सीधे तौर पर कॉन्फ़िगर नहीं किए जाते हैं. हालांकि, उनमें इस्तेमाल किए जाने वाले बिल्ड टाइप और प्रॉडक्ट के फ़्लेवर कॉन्फ़िगर किए जा सकते हैं.
उदाहरण के लिए, "डेमो" प्रॉडक्ट फ़्लेवर में कुछ सुविधाओं और डिवाइस की ज़रूरी शर्तों के बारे में बताया जा सकता है. जैसे, कस्टम सोर्स कोड, संसाधन, और एपीआई के लिए कम से कम लेवल. वहीं, "डीबग" बिल्ड टाइप, अलग-अलग बिल्ड और पैकेजिंग सेटिंग लागू करता है. जैसे, डीबग के विकल्प और हस्ताक्षर करने की कुंजियां. इन दोनों को मिलाकर बनाया गया बिल्ड वैरिएंट, आपके ऐप्लिकेशन का "demoDebug" वर्शन होता है. इसमें "demo" प्रॉडक्ट फ़्लेवर, "debug" बिल्ड टाइप, और main/
सोर्स सेट में शामिल कॉन्फ़िगरेशन और संसाधनों का कॉम्बिनेशन शामिल होता है.
बिल्ड टाइप कॉन्फ़िगर करना
मॉड्यूल-लेवल build.gradle.kts
फ़ाइल के android
ब्लॉक में, बिल्ड टाइप बनाए और कॉन्फ़िगर किए जा सकते हैं. कोई नया मॉड्यूल बनाने पर, Android Studio अपने-आप डीबग और रिलीज़ के तरह के बिल्ड
बना देता है. बिल्ड कॉन्फ़िगरेशन फ़ाइल में डीबग बिल्ड टाइप नहीं दिखता है, लेकिन Android Studio इसे debuggable
true
के साथ कॉन्फ़िगर करता है. इसकी मदद से, सुरक्षित Android डिवाइसों पर ऐप्लिकेशन को डीबग किया जा सकता है. साथ ही, सामान्य डीबग कीस्टोर की मदद से, ऐप्लिकेशन साइनिंग को कॉन्फ़िगर किया जा सकता है.
अगर आपको कुछ सेटिंग जोड़नी हैं या उनमें बदलाव करना है, तो अपने कॉन्फ़िगरेशन में डिबग बिल्ड टाइप जोड़ा जा सकता है. यहां दिए गए सैंपल में, डीबग बिल्ड टाइप के लिए
applicationIdSuffix
बताया गया है. साथ ही, "स्टैजिंग" बिल्ड टाइप को कॉन्फ़िगर किया गया है, जिसे डीबग बिल्ड टाइप की सेटिंग का इस्तेमाल करके शुरू किया जाता है:
Kotlin
android { defaultConfig { manifestPlaceholders["hostName"] = "www.example.com" ... } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } getByName("debug") { applicationIdSuffix = ".debug" isDebuggable = true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ create("staging") { initWith(getByName("debug")) manifestPlaceholders["hostName"] = "internal.example.com" applicationIdSuffix = ".debugStaging" } } }
ग्रूवी
android { defaultConfig { manifestPlaceholders = [hostName:"www.example.com"] ... } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix ".debug" debuggable true } /** * The `initWith` property lets you copy configurations from other build types, * then configure only the settings you want to change. This one copies the debug build * type, and then changes the manifest placeholder and application ID. */ staging { initWith debug manifestPlaceholders = [hostName:"internal.example.com"] applicationIdSuffix ".debugStaging" } } }
ध्यान दें: किसी बिल्ड कॉन्फ़िगरेशन फ़ाइल में बदलाव करने पर, Android Studio आपसे अपने प्रोजेक्ट को नए कॉन्फ़िगरेशन के साथ सिंक करने के लिए कहता है. अपने प्रोजेक्ट को सिंक करने के लिए, बदलाव करने पर दिखने वाले सूचना बार में, अभी सिंक करें पर क्लिक करें. इसके अलावा, टूलबार में जाकर, प्रोजेक्ट सिंक करें पर भी क्लिक किया जा सकता है. अगर Android Studio को आपके कॉन्फ़िगरेशन में कोई गड़बड़ी दिखती है, तो समस्या के बारे में बताने के लिए मैसेज विंडो दिखती है.
उन सभी प्रॉपर्टी के बारे में ज़्यादा जानने के लिए जिन्हें बिल्ड टाइप के साथ कॉन्फ़िगर किया जा सकता है,
BuildType
रेफ़रंस पढ़ें.
प्रॉडक्ट के अलग-अलग वर्शन कॉन्फ़िगर करना
प्रॉडक्ट फ़्लेवर बनाना, बिल्ड टाइप बनाने जैसा ही है. अपने बिल्ड कॉन्फ़िगरेशन में,
productFlavors
ब्लॉक में प्रॉडक्ट फ़्लेवर जोड़ें और अपनी पसंद की सेटिंग शामिल करें.
प्रॉडक्ट के फ़्लेवर, defaultConfig
के साथ काम करने वाली प्रॉपर्टी के साथ काम करते हैं, क्योंकि defaultConfig
असल में
ProductFlavor
क्लास से जुड़ा है. इसका मतलब है कि आप defaultConfig
ब्लॉक में सभी फ़्लेवर के लिए बेस कॉन्फ़िगरेशन दे सकते हैं. साथ ही, हर फ़्लेवर इनमें से किसी भी डिफ़ॉल्ट वैल्यू को बदल सकता है, जैसे कि applicationId
. ऐप्लिकेशन आईडी के बारे में ज़्यादा जानने के लिए, ऐप्लिकेशन आईडी सेट करना लेख पढ़ें.
ध्यान दें: आपको अब भी main/
मेनिफ़ेस्ट फ़ाइल में,
package
एट्रिब्यूट का इस्तेमाल करके पैकेज का नाम बताना होगा. आपको अपने सोर्स कोड में उस पैकेज के नाम का भी इस्तेमाल करना होगा, ताकि R
क्लास को रेफ़र किया जा सके या किसी भी गतिविधि या सेवा के रजिस्ट्रेशन से जुड़ी समस्या को हल किया जा सके. इससे, applicationId
का इस्तेमाल करके, हर प्रॉडक्ट फ़्लेवर को पैकेजिंग और डिस्ट्रिब्यूशन के लिए यूनीक आईडी दिया जा सकता है. इसके लिए, आपको अपने सोर्स कोड में बदलाव करने की ज़रूरत नहीं है.
सभी फ़्लेवर, नाम वाले फ़्लेवर डाइमेंशन से जुड़े होने चाहिए. यह प्रॉडक्ट के फ़्लेवर का ग्रुप होता है. आपको सभी फ़्लेवर को किसी फ़्लेवर डाइमेंशन को असाइन करना होगा; ऐसा न करने पर, आपको बिल्ड से जुड़ी यह गड़बड़ी दिखेगी.
Error: All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is not assigned to a flavor dimension.
अगर किसी दिए गए मॉड्यूल में सिर्फ़ एक फ़्लेवर डाइमेंशन है, तो 'Android Gradle प्लग इन' अपने-आप उस डाइमेंशन के लिए सभी मॉड्यूल के सभी फ़्लेवर असाइन कर देता है.
यहां दिया गया कोड सैंपल, "version" नाम का फ़्लेवर डाइमेंशन बनाता है और "demo" और "full" प्रॉडक्ट फ़्लेवर जोड़ता है. ये फ़्लेवर, अपने-आप
applicationIdSuffix
और
versionNameSuffix
उपलब्ध कराते हैं:
Kotlin
android { ... defaultConfig {...} buildTypes { getByName("debug"){...} getByName("release"){...} } // Specifies one flavor dimension. flavorDimensions += "version" productFlavors { create("demo") { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension = "version" applicationIdSuffix = ".demo" versionNameSuffix = "-demo" } create("full") { dimension = "version" applicationIdSuffix = ".full" versionNameSuffix = "-full" } } }
Groovy
android { ... defaultConfig {...} buildTypes { debug{...} release{...} } // Specifies one flavor dimension. flavorDimensions "version" productFlavors { demo { // Assigns this product flavor to the "version" flavor dimension. // If you are using only one dimension, this property is optional, // and the plugin automatically assigns all the module's flavors to // that dimension. dimension "version" applicationIdSuffix ".demo" versionNameSuffix "-demo" } full { dimension "version" applicationIdSuffix ".full" versionNameSuffix "-full" } } }
ध्यान दें: अगर आपके पास (अगस्त 2021 से पहले बनाया गया) कोई ऐसा लेगसी ऐप्लिकेशन है जिसे Google Play पर APK का इस्तेमाल करके डिस्ट्रिब्यूट किया जाता है, तो Google Play में APK पर एक से ज़्यादा सहायता का इस्तेमाल करके अपने ऐप्लिकेशन को डिस्ट्रिब्यूट किया जा सकता है. ऐसे में, सभी वैरिएंट के लिए applicationId
की एक जैसी वैल्यू असाइन करें और हर वैरिएंट के लिए अलग versionCode
वैल्यू सबमिट करें. Google Play पर
अपने ऐप्लिकेशन के अलग-अलग वैरिएंट को अलग-अलग ऐप्लिकेशन के तौर पर उपलब्ध कराने के लिए, आपको हर वैरिएंट के लिए अलग-अलग applicationId
असाइन करना होगा.
प्रॉडक्ट के फ़्लेवर बनाने और उन्हें कॉन्फ़िगर करने के बाद, सूचना बार में अभी सिंक करें पर क्लिक करें. सिंक पूरा होने के बाद, Gradle
आपके बिल्ड टाइप और प्रॉडक्ट के फ़्लेवर के आधार पर अपने-आप बिल्ड वैरिएंट बनाता है और
<product-flavor><Build-Type>
के हिसाब से उनके नाम रखता है. उदाहरण के लिए, अगर आपने प्रॉडक्ट के "डेमो" और "फ़ुल" फ़्लेवर बनाए हैं और डिफ़ॉल्ट "डीबग" और "रिलीज़" बिल्ड टाइप को बनाए रखा है, तो Gradle इन बिल्ड टाइप को बनाता है:
-
demoDebug
-
demoRelease
-
fullDebug
-
fullRelease
यह चुनने के लिए कि किस बिल्ड वैरिएंट को बनाना और चलाना है, बिल्ड करें > बिल्ड वैरिएंट चुनें पर जाएं और मेन्यू से कोई बिल्ड वैरिएंट चुनें. हर बिल्ड वैरिएंट को अपनी सुविधाओं और संसाधनों के हिसाब से कस्टमाइज़ करने के लिए, आपको इस पेज पर बताए गए तरीके से सोर्स सेट बनाने और उन्हें मैनेज करने होंगे.
बिल्ड के वैरिएंट के लिए ऐप्लिकेशन आईडी बदलें
अपने ऐप्लिकेशन के लिए APK या AAB बनाते समय, बिल्ड टूल ऐप्लिकेशन को build.gradle.kts
फ़ाइल के defaultConfig
ब्लॉक में बताए गए ऐप्लिकेशन आईडी से टैग करते हैं. इस बारे में नीचे दिए गए उदाहरण में बताया गया है. हालांकि, अगर आपको अपने ऐप्लिकेशन के अलग-अलग वर्शन बनाकर, उन्हें Google Play Store पर अलग-अलग लिस्टिंग के तौर पर दिखाना है, जैसे कि "मुफ़्त" और "प्रॉफ़ेशनल" वर्शन, तो आपको अलग-अलग बिल्ड वैरिएंट बनाने होंगे. इनमें से हर एक का ऐप्लिकेशन आईडी अलग-अलग होना चाहिए.
इस मामले में, हर बिल्ड वैरिएंट को एक अलग प्रॉडक्ट फ़्लेवर के तौर पर तय करें. productFlavors
ब्लॉक में मौजूद हर फ़्लेवर के लिए, applicationId
प्रॉपर्टी को फिर से तय किया जा सकता है. इसके अलावा, applicationIdSuffix
का इस्तेमाल करके डिफ़ॉल्ट ऐप्लिकेशन आईडी में सेगमेंट जोड़ा जा सकता है, जैसा कि यहां दिखाया गया है:
Kotlin
android { defaultConfig { applicationId = "com.example.myapp" } productFlavors { create("free") { applicationIdSuffix = ".free" } create("pro") { applicationIdSuffix = ".pro" } } }
ग्रूवी
android { defaultConfig { applicationId "com.example.myapp" } productFlavors { free { applicationIdSuffix ".free" } pro { applicationIdSuffix ".pro" } } }
इस तरह, "मुफ़्त" प्रॉडक्ट फ़्लेवर के लिए ऐप्लिकेशन आईडी, "com.example.myapp.free" होगा.
applicationIdSuffix
का इस्तेमाल करके, बिल्ड टाइप के आधार पर सेगमेंट जोड़ा जा सकता है. इसका उदाहरण यहां दिया गया है:
Kotlin
android { ... buildTypes { getByName("debug") { applicationIdSuffix = ".debug" } } }
ग्रूवी
android { ... buildTypes { debug { applicationIdSuffix ".debug" } } }
Gradle, प्रॉडक्ट फ़्लेवर के बाद बिल्ड टाइप कॉन्फ़िगरेशन लागू करता है. इसलिए, "मुफ़्त डीबग" बिल्ड वैरिएंट के लिए ऐप्लिकेशन आईडी, "com.example.myapp.free.debug" है. यह तब फ़ायदेमंद होता है, जब आपको एक ही डिवाइस में डीबग और रिलीज़, दोनों को रखना हो, क्योंकि किसी भी दो ऐप्लिकेशन का ऐप्लिकेशन आईडी एक जैसा नहीं हो सकता.
अगर आपके पास अगस्त 2021 से पहले बनाया गया कोई लेगसी ऐप्लिकेशन है, जिसे Google Play पर APKs का इस्तेमाल करके डिस्ट्रिब्यूट किया जाता है और आपको एक ही ऐप्लिकेशन लिस्टिंग का इस्तेमाल करके, कई APKs डिस्ट्रिब्यूट करने हैं, तो हर APK को एक अलगversionCode
दें. साथ ही, हर APK के लिए एक ही ऐप्लिकेशन आईडी का इस्तेमाल करें. ज़्यादा जानकारी के लिए, एक से ज़्यादा APK इस्तेमाल करने की सुविधा के बारे में पढ़ें. AABs का इस्तेमाल करके पब्लिश करने पर कोई असर नहीं पड़ता, क्योंकि इसमें एक आर्टफ़ैक्ट का इस्तेमाल किया जाता है. यह आर्टफ़ैक्ट डिफ़ॉल्ट रूप से एक वर्शन कोड और ऐप्लिकेशन आईडी का इस्तेमाल करता है.
सलाह: अगर आपको अपनी मेनिफ़ेस्ट फ़ाइल में ऐप्लिकेशन आईडी का रेफ़रंस देना है, तो किसी भी मेनिफ़ेस्ट एट्रिब्यूट में ${applicationId}
प्लेसहोल्डर का इस्तेमाल किया जा सकता है. बिल्ड के दौरान, Gradle इस टैग को असली ऐप्लिकेशन आईडी से बदल देता है. ज़्यादा जानकारी के लिए, मेनिफ़ेस्ट में बिल्ड वैरिएबल इंजेक्ट करना लेख पढ़ें.
फ़्लेवर डाइमेंशन की मदद से, प्रॉडक्ट के कई फ़्लेवर को जोड़ना
कुछ मामलों में, आपको कई प्रॉडक्ट के वर्शन के कॉन्फ़िगरेशन को एक साथ जोड़ना पड़ सकता है. उदाहरण के लिए, हो सकता है कि आप एपीआई लेवल के आधार पर, "पूरे" और "डेमो" प्रॉडक्ट फ़्लेवर के लिए अलग-अलग कॉन्फ़िगरेशन बनाना चाहें. ऐसा करने के लिए, Android Gradle प्लग इन की मदद से, प्रॉडक्ट के अलग-अलग वर्शन के कई ग्रुप बनाए जा सकते हैं. इन्हें, वर्शन के डाइमेंशन के तौर पर बनाया जाता है.
आपके ऐप्लिकेशन को बिल्ड करते समय, Gradle आपके तय किए गए हर फ़्लेवर डाइमेंशन के प्रॉडक्ट फ़्लेवर कॉन्फ़िगरेशन को, बिल्ड टाइप कॉन्फ़िगरेशन के साथ जोड़ता है. इससे, फ़ाइनल बिल्ड वैरिएंट बनता है. Gradle, एक ही फ़्लेवर डाइमेंशन से जुड़े प्रॉडक्ट फ़्लेवर को एक साथ नहीं जोड़ता.
नीचे दिया गया कोड सैंपल,
flavorDimensions
प्रॉपर्टी का इस्तेमाल करके "मोड" फ़्लेवर वाला डाइमेंशन
बनाता है, ताकि प्रॉडक्ट के "फ़ुल" और "डेमो" फ़्लेवर को ग्रुप किया जा सके. साथ ही, एपीआई लेवल के आधार पर, प्रॉडक्ट के फ़्लेवर के कॉन्फ़िगरेशन को ग्रुप करने के लिए, "एपीआई"
फ़्लेवर डाइमेंशन का इस्तेमाल किया गया हो:
Kotlin
android { ... buildTypes { getByName("debug") {...} getByName("release") {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions += listOf("api", "mode") productFlavors { create("demo") { // Assigns this product flavor to the "mode" flavor dimension. dimension = "mode" ... } create("full") { dimension = "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. create("minApi24") { dimension = "api" minSdk = 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode = 30000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi24" ... } create("minApi23") { dimension = "api" minSdk = 23 versionCode = 20000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi23" ... } create("minApi21") { dimension = "api" minSdk = 21 versionCode = 10000 + (android.defaultConfig.versionCode ?: 0) versionNameSuffix = "-minApi21" ... } } } ...
Groovy
android { ... buildTypes { debug {...} release {...} } // Specifies the flavor dimensions you want to use. The order in which you // list the dimensions determines their priority, from highest to lowest, // when Gradle merges variant sources and configurations. You must assign // each product flavor you configure to one of the flavor dimensions. flavorDimensions "api", "mode" productFlavors { demo { // Assigns this product flavor to the "mode" flavor dimension. dimension "mode" ... } full { dimension "mode" ... } // Configurations in the "api" product flavors override those in "mode" // flavors and the defaultConfig block. Gradle determines the priority // between flavor dimensions based on the order in which they appear next // to the flavorDimensions property, with the first dimension having a higher // priority than the second, and so on. minApi24 { dimension "api" minSdkVersion 24 // To ensure the target device receives the version of the app with // the highest compatible API level, assign version codes in increasing // value with API level. versionCode 30000 + android.defaultConfig.versionCode versionNameSuffix "-minApi24" ... } minApi23 { dimension "api" minSdkVersion 23 versionCode 20000 + android.defaultConfig.versionCode versionNameSuffix "-minApi23" ... } minApi21 { dimension "api" minSdkVersion 21 versionCode 10000 + android.defaultConfig.versionCode versionNameSuffix "-minApi21" ... } } } ...
Gradle जिन बिल्ड वैरिएंट को बनाता है उनकी संख्या, हर फ़्लेवर डाइमेंशन में मौजूद फ़्लेवर की संख्या और कॉन्फ़िगर किए गए बिल्ड टाइप की संख्या के गुणनफल के बराबर होती है. जब Gradle हर बिल्ड वैरिएंट या उससे जुड़े आर्टफ़ैक्ट को नाम देता है, तो सबसे ज़्यादा प्राथमिकता वाले फ़्लेवर डाइमेंशन के प्रॉडक्ट फ़्लेवर सबसे पहले दिखते हैं. इसके बाद, कम प्राथमिकता वाले डाइमेंशन के प्रॉडक्ट फ़्लेवर दिखते हैं. आखिर में, बिल्ड टाइप दिखता है.
उदाहरण के तौर पर, पिछले बिल्ड कॉन्फ़िगरेशन का इस्तेमाल करके, Gradle कुल 12 बिल्ड वैरिएंट बनाता है. इनका नाम इस तरीके से रखा जाता है:
- बिल्ड वैरिएंट:
[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
- संबंधित APK:
app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
- उदाहरण के लिए,
- बिल्ड वैरिएंट:
minApi24DemoDebug
- इससे जुड़ा APK:
app-minApi24-demo-debug.apk
हर प्रॉडक्ट के फ़्लेवर और वैरिएंट के हिसाब से सोर्स सेट डायरेक्ट्री बनाने के अलावा, प्रॉडक्ट के हर फ़्लेवर के कॉम्बिनेशन के लिए भी सोर्स सेट डायरेक्ट्री बनाई जा सकती हैं. उदाहरण के लिए, आपके पास
src/demoMinApi24/java/
डायरेक्ट्री में Java सोर्स बनाने और जोड़ने का विकल्प है.
Gradle, इन सोर्स का इस्तेमाल सिर्फ़ तब करता है, जब कोई ऐसा वैरिएंट तैयार किया जाता है जिसमें इन दोनों प्रॉडक्ट के फ़्लेवर को मिलाया जाता है.
प्रॉडक्ट फ़्लेवर के कॉम्बिनेशन के लिए बनाए गए सोर्स सेट, हर प्रॉडक्ट फ़्लेवर के सोर्स सेट की तुलना में ज़्यादा प्राथमिकता पाते हैं. सोर्स सेट और Gradle के ज़रिए संसाधनों को मर्ज करने के तरीके के बारे में ज़्यादा जानने के लिए, सोर्स सेट बनाने का तरीका बताने वाला सेक्शन पढ़ें.
वैरिएंट फ़िल्टर करना
Gradle, कॉन्फ़िगर किए गए प्रॉडक्ट के हर संभावित कॉम्बिनेशन के लिए, एक बिल्ड वैरिएंट बनाता है. हालांकि, बिल्ड के कुछ ऐसे वैरिएंट हो सकते हैं जिनकी आपको ज़रूरत नहीं है या जिनका आपके प्रोजेक्ट के हिसाब से कोई
मतलब न हो. बिल्ड वैरिएंट के कुछ कॉन्फ़िगरेशन हटाने के लिए,
अपने मॉड्यूल-लेवल की build.gradle.kts
फ़ाइल में वैरिएंट फ़िल्टर बनाएं.
उदाहरण के तौर पर, पिछले सेक्शन के बिल्ड कॉन्फ़िगरेशन का इस्तेमाल करके, मान लें कि आपको ऐप्लिकेशन के डेमो वर्शन के लिए, सिर्फ़ एपीआई लेवल 23 और उसके बाद वाले लेवल ही काम करने हैं.
variantFilter
ब्लॉक का इस्तेमाल करके, बिल्ड के ऐसे सभी वैरिएंट
कॉन्फ़िगरेशन फ़िल्टर किए जा सकते हैं जिनमें "minApi21" और "डेमो" प्रॉडक्ट के फ़्लेवर शामिल होते हैं:
Kotlin
android { ... buildTypes {...} flavorDimensions += listOf("api", "mode") productFlavors { create("demo") {...} create("full") {...} create("minApi24") {...} create("minApi23") {...} create("minApi21") {...} } } androidComponents { beforeVariants { variantBuilder -> // To check for a certain build type, use variantBuilder.buildType == "<buildType>" if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) { // Gradle ignores any variants that satisfy the conditions above. variantBuilder.enable = false } } } ...
Groovy
android { ... buildTypes {...} flavorDimensions "api", "mode" productFlavors { demo {...} full {...} minApi24 {...} minApi23 {...} minApi21 {...} } variantFilter { variant -> def names = variant.flavors*.name // To check for a certain build type, use variant.buildType.name == "<buildType>" if (names.contains("minApi21") && names.contains("demo")) { // Gradle ignores any variants that satisfy the conditions above. setIgnore(true) } } } ...
अपने बिल्ड कॉन्फ़िगरेशन में वैरिएंट फ़िल्टर जोड़ने और सूचना बार में अभी सिंक करें पर क्लिक करने के बाद, Gradle उन सभी बिल्ड वैरिएंट को अनदेखा कर देता है जो आपकी बताई गई शर्तों को पूरा करते हैं. मेन्यू बार में बिल्ड > बिल्ड वैरिएंट चुनें पर क्लिक करने पर, अब मेन्यू में बिल्ड वैरिएंट नहीं दिखते. इसके अलावा, टूल विंडो बार में बिल्ड वैरिएंट पर क्लिक करने पर भी ऐसा ही होता है.
सोर्स सेट बनाना
डिफ़ॉल्ट रूप से, Android Studio main/
सोर्स सेट और डायरेक्ट्री बनाता है. ऐसा उन सभी चीज़ों के लिए किया जाता है जिन्हें आपको अपने सभी बिल्ड वैरिएंट के बीच शेयर करना है. हालांकि, आपके पास नए सोर्स सेट बनाने का विकल्प है. इससे यह कंट्रोल किया जा सकता है कि Gradle किन फ़ाइलों को कंपाइल और पैकेज करे. साथ ही, इससे यह भी कंट्रोल किया जा सकता है कि अलग-अलग तरह के बिल्ड, प्रॉडक्ट फ़्लेवर, प्रॉडक्ट फ़्लेवर के कॉम्बिनेशन (फ़्लेवर डाइमेंशन का इस्तेमाल करते समय), और बिल्ड वैरिएंट के लिए कौनसी फ़ाइलें कंपाइल और पैकेज की जाएं.
उदाहरण के लिए, main/
सोर्स सेट में बुनियादी फ़ंक्शन तय किए जा सकते हैं. साथ ही, अलग-अलग क्लाइंट के लिए अपने ऐप्लिकेशन की ब्रैंडिंग बदलने के लिए, प्रॉडक्ट फ़्लेवर सोर्स सेट का इस्तेमाल किया जा सकता है. इसके अलावा, सिर्फ़ डीबग बिल्ड टाइप का इस्तेमाल करने वाले बिल्ड वैरिएंट के लिए, खास अनुमतियां और लॉगिंग फ़ंक्शन शामिल किए जा सकते हैं.
Gradle, सोर्स सेट की फ़ाइलों और डायरेक्ट्री को एक खास तरीके से व्यवस्थित
करता है, जो main/
के सोर्स सेट की तरह होता है. उदाहरण के लिए, Gradle के हिसाब से, "डीबग" बिल्ड टाइप के लिए खास तौर पर बनाई गई Kotlin या Java क्लास फ़ाइलें, src/debug/kotlin/
या src/debug/java/
डायरेक्ट्री में होनी चाहिए.
Android Gradle प्लग इन, एक काम का Gradle टास्क उपलब्ध कराता है. इससे आपको हर बिल्ड टाइप, प्रॉडक्ट के हर फ़्लेवर, और बिल्ड वैरिएंट के लिए, अपनी फ़ाइलों को व्यवस्थित करने का तरीका पता चलता है. उदाहरण के लिए, टास्क के आउटपुट से मिले इस सैंपल में बताया गया है कि Gradle को "डीबग" बिल्ड टाइप के लिए, कुछ फ़ाइलें कहां मिल सकती हैं:
------------------------------------------------------------ Project :app ------------------------------------------------------------ ... debug ---- Compile configuration: debugCompile build.gradle name: android.sourceSets.debug Java sources: [app/src/debug/java] Kotlin sources: [app/src/debug/kotlin, app/src/debug/java] Manifest file: app/src/debug/AndroidManifest.xml Android resources: [app/src/debug/res] Assets: [app/src/debug/assets] AIDL sources: [app/src/debug/aidl] RenderScript sources: [app/src/debug/rs] JNI sources: [app/src/debug/jni] JNI libraries: [app/src/debug/jniLibs] Java-style resources: [app/src/debug/resources]
यह आउटपुट देखने के लिए, यह तरीका अपनाएं:
- टूल विंडो बार में, Gradle पर क्लिक करें.
MyApplication > Tasks > android पर जाएं और sourceSets पर दो बार क्लिक करें.
Tasks फ़ोल्डर देखने के लिए, आपको सिंक करने के दौरान Gradle को टास्क की सूची बनाने की अनुमति देनी होगी. ऐसा करने के लिए, यहां दिया गया तरीका अपनाएं:
- फ़ाइल > सेटिंग > एक्सपेरिमेंटल (macOS पर Android Studio > सेटिंग > एक्सपेरिमेंटल ) पर क्लिक करें.
- Gredle सिंक करने के दौरान, Gradle टास्क सूची न बनाएं से चुने हुए का निशान हटाएं.
- Gradle के टास्क को पूरा करने के बाद, रन विंडो खुलती है, ताकि आउटपुट दिखाया जा सके.
ध्यान दें: टास्क के आउटपुट में, उन फ़ाइलों के लिए सोर्स सेट व्यवस्थित करने का तरीका भी दिखता है जिनका इस्तेमाल आपको अपने ऐप्लिकेशन की जांच करने के लिए करना है. जैसे, test/
और androidTest/
टेस्टिंग सोर्स सेट.
बिल्ड का नया वैरिएंट बनाने पर, Android Studio आपके लिए सोर्स
सेट की डायरेक्ट्री नहीं बनाता. हालांकि, इसमें आपकी मदद के लिए कुछ विकल्प उपलब्ध होते हैं. उदाहरण के लिए, अपने "डबग" बिल्ड टाइप के लिए सिर्फ़ java/
डायरेक्ट्री बनाने के लिए:
- प्रोजेक्ट पैनल खोलें और पैनल के सबसे ऊपर मौजूद मेन्यू से, प्रोजेक्ट व्यू चुनें.
MyProject/app/src/
पर जाएं.src
डायरेक्ट्री पर राइट क्लिक करें और नया > डायरेक्ट्री चुनें.- Gradle सोर्स सेट में मौजूद मेन्यू से, full/java चुनें.
- Enter दबाएं.
Android Studio, डीबग बिल्ड टाइप के लिए सोर्स सेट डायरेक्ट्री बनाता है और फिर उसके अंदर java/
डायरेक्ट्री बनाता है. इसके अलावा, किसी खास बिल्ड वैरिएंट के लिए अपने प्रोजेक्ट में नई फ़ाइल जोड़ने पर, Android Studio आपके लिए डायरेक्ट्री बना सकता है.
उदाहरण के लिए, अपने "डीबग" बिल्ड टाइप के लिए, वैल्यू वाली एक्सएमएल फ़ाइल बनाने का तरीका:
- प्रोजेक्ट पैनल में,
src
डायरेक्ट्री पर दायां क्लिक करें और नया > एक्सएमएल > वैल्यू एक्सएमएल फ़ाइल चुनें. - एक्सएमएल फ़ाइल का नाम डालें या डिफ़ॉल्ट नाम रखें.
- टारगेट सोर्स सेट के बगल में मौजूद मेन्यू से, डीबग करें को चुनें.
- पूरा करें पर क्लिक करें.
टारगेट सोर्स सेट के तौर पर "डीबग" बिल्ड टाइप तय किया गया था. इसलिए, Android Studio, एक्सएमएल फ़ाइल बनाते समय ज़रूरी डायरेक्ट्री अपने-आप बना देता है. इससे बनने वाला डायरेक्ट्री स्ट्रक्चर, पहली इमेज में दिखाए गए स्ट्रक्चर जैसा दिखता है.
ऐक्टिव सोर्स सेट के आइकॉन में हरे रंग का इंंडिकेटर होता है. इससे पता चलता है कि वे चालू हैं. debug
के सोर्स सेट को [main]
के साथ सफ़िक्स को जोड़ा गया है, ताकि यह दिखाया जा सके कि इसे main
के सोर्स सेट में मर्ज कर दिया जाएगा.
इसी प्रोसेस का इस्तेमाल करके, src/demo/
जैसे प्रॉडक्ट फ़्लेवर के लिए सोर्स सेट डायरेक्ट्री भी बनाई जा सकती हैं. साथ ही, src/demoDebug/
जैसे वैरिएंट भी बनाए जा सकते हैं. इसके अलावा, ऐसे टेस्टिंग सोर्स सेट भी बनाए जा सकते हैं जो src/androidTestDemoDebug/
जैसे खास बिल्ड वैरिएंट को टारगेट करते हैं. ज़्यादा जानने के लिए, सोर्स सेट की जांच करने के बारे में पढ़ें.
सोर्स सेट के डिफ़ॉल्ट कॉन्फ़िगरेशन बदलना
अगर आपके पास ऐसे सोर्स हैं जिन्हें डिफ़ॉल्ट सोर्स सेट फ़ाइल के स्ट्रक्चर में व्यवस्थित नहीं किया गया है, जैसा कि सोर्स सेट बनाने के बारे में पिछले सेक्शन में बताया गया है, तो
sourceSets
ब्लॉक का इस्तेमाल करके, यह बदला जा सकता है कि Gradle, सोर्स सेट के हर कॉम्पोनेंट के लिए फ़ाइलें कहां से इकट्ठा करे.
sourceSets
ब्लॉक, android
ब्लॉक में होना चाहिए. आपको सोर्स फ़ाइलों को कहीं और ले जाने की ज़रूरत नहीं है. आपको सिर्फ़ Gradle को मॉड्यूल-लेवल build.gradle.kts
फ़ाइल के हिसाब से पाथ देना होगा, जहां Gradle हर सोर्स सेट कॉम्पोनेंट के लिए फ़ाइलें ढूंढ सकता है. यह जानने के लिए कि किन कॉम्पोनेंट को कॉन्फ़िगर किया जा सकता है और क्या उन्हें एक से ज़्यादा फ़ाइलों या डायरेक्ट्री पर मैप किया जा सकता है, Android Gradle प्लगिन एपीआई रेफ़रंस देखें.
नीचे दिया गया कोड सैंपल, app/other/
डायरेक्ट्री के सोर्स को main
सोर्स सेट के कुछ कॉम्पोनेंट पर मैप करता है. साथ ही, androidTest
सोर्स सेट की रूट डायरेक्ट्री को बदलता है:
Kotlin
android { ... // Encapsulates configurations for the main source set. sourceSets.getByName("main") { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.setSrcDirs(listOf("other/java")) // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.setSrcDirs(listOf("other/res1", "other/res2")) // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile("other/AndroidManifest.xml") ... } // Create additional blocks to configure other source sets. sourceSets.getByName("androidTest") { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot("src/tests") ... } } ...
ग्रूवी
android { ... sourceSets { // Encapsulates configurations for the main source set. main { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.srcDirs = ['other/java'] // If you list multiple directories, Gradle uses all of them to collect // sources. Because Gradle gives these directories equal priority, if // you define the same resource in more than one directory, you receive an // error when merging resources. The default directory is 'src/main/res'. res.srcDirs = ['other/res1', 'other/res2'] // Note: Avoid specifying a directory that is a parent to one // or more other directories you specify. For example, avoid the following: // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings'] // Specify either only the root 'other/res1' directory or only the // nested 'other/res1/layouts' and 'other/res1/strings' directories. // For each source set, you can specify only one Android manifest. // By default, Android Studio creates a manifest for your main source // set in the src/main/ directory. manifest.srcFile 'other/AndroidManifest.xml' ... } // Create additional blocks to configure other source sets. androidTest { // If all the files for a source set are located under a single root // directory, you can specify that directory using the setRoot property. // When gathering sources for the source set, Gradle looks only in locations // relative to the root directory you specify. For example, after applying the // configuration below for the androidTest source set, Gradle looks for Java // sources only in the src/tests/java/ directory. setRoot 'src/tests' ... } } } ...
ध्यान दें कि सोर्स डायरेक्ट्री सिर्फ़ एक सोर्स सेट से जुड़ी हो सकती है. उदाहरण के लिए, एक ही टेस्ट सोर्स को test
और androidTest
, दोनों सोर्स सेट के साथ शेयर नहीं किया जा सकता. ऐसा इसलिए होता है, क्योंकि Android Studio हर सोर्स सेट के लिए अलग-अलग IntelliJ मॉड्यूल बनाता है. साथ ही, यह सोर्स सेट में डुप्लीकेट कॉन्टेंट रूट के साथ काम नहीं कर सकता.
सोर्स सेट की मदद से बनाएं
सोर्स सेट डायरेक्ट्री का इस्तेमाल करके, ऐसे कोड और संसाधन शामिल किए जा सकते हैं जिन्हें आपको सिर्फ़ कुछ कॉन्फ़िगरेशन के साथ पैकेज करना है. उदाहरण के लिए, अगर "demoDebug" बिल्ड वैरिएंट बनाया जा रहा है, जो "demo" प्रॉडक्ट फ़्लेवर और "debug" बिल्ड टाइप का क्रॉसप्रॉडक्ट है, तो Gradle इन डायरेक्ट्री को देखता है और उन्हें यह प्राथमिकता देता है:
-
src/demoDebug/
(बिल्ड वैरिएंट का सोर्स सेट) -
src/debug/
(बिल्ड टाइप सोर्स सेट) -
src/demo/
(प्रॉडक्ट फ़्लेवर का सोर्स सेट) -
src/main/
(मुख्य सोर्स सेट)
प्रॉडक्ट के स्वाद के कॉम्बिनेशन के लिए बनाए गए सोर्स सेट में, स्वाद के सभी डाइमेंशन शामिल होने चाहिए. उदाहरण के लिए, बिल्ड के वैरिएंट के सोर्स के सेट में, बिल्ड टाइप और सभी फ़्लेवर डाइमेंशन का कॉम्बिनेशन होना चाहिए. ऐसे फ़ोल्डर में मौजूद कोड और संसाधनों को मर्ज नहीं किया जा सकता जो एक से ज़्यादा, लेकिन सभी फ़्लेवर डाइमेंशन को कवर नहीं करते.
अगर एक से ज़्यादा प्रॉडक्ट के फ़्लेवर को एक साथ जोड़ा जाता है, तो प्रॉडक्ट के फ़्लेवर के बीच प्राथमिकता तय करने के लिए, यह देखा जाता है कि वे किस फ़्लेवर डाइमेंशन से जुड़े हैं.
android.flavorDimensions
प्रॉपर्टी की मदद से फ़्लेवर डाइमेंशन की सूची बनाते समय, सूची में शामिल पहले फ़्लेवर डाइमेंशन के प्रॉडक्ट फ़्लेवर को, दूसरे फ़्लेवर डाइमेंशन के प्रॉडक्ट फ़्लेवर के मुकाबले ज़्यादा प्राथमिकता दी जाती है. इसके अलावा,
प्रॉडक्ट फ़्लेवर के कॉम्बिनेशन के लिए बनाए गए सोर्स सेट को,
किसी एक प्रॉडक्ट फ़्लेवर के सोर्स सेट के मुकाबले ज़्यादा प्राथमिकता दी जाती है.
प्राथमिकता के क्रम से यह तय होता है कि Gradle कोड और संसाधनों को जोड़ते समय, किस सोर्स सेट को ज़्यादा प्राथमिकता देगा. demoDebug/
सोर्स सेट डायरेक्ट्री में, बिल्ड वैरिएंट के लिए खास तौर पर बनी फ़ाइलें मौजूद हो सकती हैं. इसलिए, अगर demoDebug/
में ऐसी फ़ाइल शामिल है जिसके बारे में debug/
में भी बताया गया है, तो Gradle, demoDebug/
सोर्स सेट में मौजूद फ़ाइल का इस्तेमाल करता है. इसी तरह, Gradle, बिल्ड टाइप और प्रॉडक्ट फ़्लेवर वाली फ़ाइलों को main/
में मौजूद फ़ाइलों के मुकाबले ज़्यादा प्राथमिकता देता है.
Gradle, नीचे दिए गए बिल्ड नियमों को लागू करते समय, प्राथमिकता के इस क्रम को ध्यान में रखता है:
- एक आउटपुट जनरेट करने के लिए,
kotlin/
याjava/
डायरेक्ट्री में मौजूद सभी सोर्स कोड को एक साथ इकट्ठा किया जाता है.ध्यान दें: किसी दिए गए बिल्ड वैरिएंट के लिए, Gradle एक गड़बड़ी दिखाता है. ऐसा तब होता है, जब उसे दो या उससे ज़्यादा सोर्स सेट डायरेक्ट्री मिलती हैं जिनमें एक ही Kotlin या Java क्लास तय की गई है. उदाहरण के लिए, डीबग ऐप्लिकेशन बनाते समय,
src/debug/Utility.kt
औरsrc/main/Utility.kt
, दोनों के बारे में जानकारी नहीं दी जा सकती. इसकी वजह यह है कि Gradle, बिल्ड प्रोसेस के दौरान इन दोनों डायरेक्ट्री को देखता है और इससे "डुप्लीकेट क्लास" की गड़बड़ी मिलती है. अगर आपको अलग-अलग बिल्ड टाइप के लिएUtility.kt
के अलग-अलग वर्शन चाहिए, तो हर बिल्ड टाइप को फ़ाइल का अपना वर्शन तय करना चाहिए. साथ ही, उसेmain/
के सोर्स सेट में शामिल नहीं करना चाहिए. - मेनिफ़ेस्ट को एक साथ मिलाकर एक मेनिफ़ेस्ट बनाया जाता है. प्राथमिकता, पिछले उदाहरण में दी गई सूची के क्रम में दी जाती है. इसका मतलब है कि किसी बिल्ड टाइप के लिए मेनिफ़ेस्ट की सेटिंग, प्रॉडक्ट फ़्लेवर के लिए मेनिफ़ेस्ट की सेटिंग को बदल देती हैं. ज़्यादा जानने के लिए, मेनिफ़ेस्ट को मर्ज करने के बारे में पढ़ें.
values/
डायरेक्ट्री में मौजूद फ़ाइलों को एक साथ मर्ज कर दिया जाता है. अगर दो फ़ाइलों का नाम एक जैसा है, जैसे कि दोstrings.xml
फ़ाइलें, तो प्राथमिकता उसी क्रम में दी जाती है जिस क्रम में पिछले उदाहरण में सूची दी गई है. इसका मतलब है कि बिल्ड टाइप सोर्स सेट में मौजूद किसी फ़ाइल में तय की गई वैल्यू, प्रॉडक्ट फ़्लेवर में मौजूद उसी फ़ाइल में तय की गई वैल्यू को बदल देती हैं.res/
औरasset/
डायरेक्ट्री में मौजूद संसाधनों को एक साथ पैकेज किया जाता है. अगर दो या उससे ज़्यादा सोर्स सेट में एक ही नाम वाले संसाधन हैं, तो प्राथमिकता उसी क्रम में दी जाती है जिस क्रम में पिछले उदाहरण में सूची दी गई है.- ऐप्लिकेशन बनाते समय, Gradle लाइब्रेरी के मॉड्यूल डिपेंडेंसी के साथ शामिल किए गए संसाधनों और मेनिफ़ेस्ट को सबसे कम प्राथमिकता देता है.
डिपेंडेंसी का एलान करना
किसी खास बिल्ड वैरिएंट या टेस्टिंग सोर्स सेट के लिए डिपेंडेंसी कॉन्फ़िगर करने के लिए, Implementation
कीवर्ड से पहले बिल्ड वैरिएंट या टेस्टिंग सोर्स सेट का नाम जोड़ें, जैसा कि इस उदाहरण में दिखाया गया है:
Kotlin
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. "freeImplementation"(project(":mylibrary")) // Adds a remote binary dependency only for local tests. testImplementation("junit:junit:4.12") // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1") }
ग्रूवी
dependencies { // Adds the local "mylibrary" module as a dependency to the "free" flavor. freeImplementation project(":mylibrary") // Adds a remote binary dependency only for local tests. testImplementation 'junit:junit:4.12' // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1' }
डिपेंडेंसी कॉन्फ़िगर करने के बारे में ज़्यादा जानने के लिए, बिल्ड डिपेंडेंसी जोड़ना लेख पढ़ें.
वैरिएंट के हिसाब से डिपेंडेंसी मैनेजमेंट का इस्तेमाल करना
'Android Gradle प्लग इन 3.0.0' और उसके बाद वाले वर्शन में, डिपेंडेंसी का एक नया तरीका शामिल किया गया है. यह
लाइब्रेरी इस्तेमाल करते समय, वैरिएंट से अपने-आप मैच करता है. इसका मतलब है कि किसी ऐप्लिकेशन का debug
वैरिएंट, लाइब्रेरी के debug
वैरिएंट का अपने-आप इस्तेमाल करता है. यह इसी तरह जारी रहता है. यह सुविधा, फ़्लेवर का इस्तेमाल करते समय भी काम करती है: ऐप्लिकेशन का freeDebug
वैरिएंट, लाइब्रेरी के freeDebug
वैरिएंट का इस्तेमाल करेगा.
प्लग इन वैरिएंट को सही तरीके से मैच कर सके, इसके लिए आपको नीचे दिए गए सेक्शन में बताए गए मिलते-जुलते फ़ॉलबैक देने होंगे. ऐसा उन मामलों में होगा जहां सीधे तौर पर मैच नहीं किया जा सकता.
उदाहरण के लिए, मान लें कि आपका ऐप्लिकेशन "स्टैजिंग" नाम के बिल्ड टाइप को कॉन्फ़िगर करता है, लेकिन उसकी लाइब्रेरी की किसी एक डिपेंडेंसी को कॉन्फ़िगर नहीं किया जाता. जब प्लग इन आपके ऐप्लिकेशन का "स्टैजिंग" वर्शन बनाने की कोशिश करता है, तो उसे यह पता नहीं चलता कि लाइब्रेरी के किस वर्शन का इस्तेमाल करना है. साथ ही, आपको गड़बड़ी का ऐसा मैसेज दिखेगा जो यहां दिए गए मैसेज से मिलता-जुलता होगा:
Error:Failed to resolve: Could not resolve project :mylibrary. Required by: project :app
वैरिएंट मैचिंग से जुड़ी बिल्ड गड़बड़ियां हल करना
इस प्लग इन में डीएसएल एलिमेंट शामिल हैं. इनकी मदद से, यह कंट्रोल किया जा सकता है कि Gradle उन स्थितियों को कैसे हल करता है जिनमें किसी ऐप्लिकेशन और डिपेंडेंसी के बीच सीधे वैरिएंट मैच नहीं हो पाता.
वैरिएंट के हिसाब से डिपेंडेंसी मैच करने से जुड़ी समस्याओं और डीएसएल प्रॉपर्टी का इस्तेमाल करके उन्हें हल करने के तरीके की सूची यहां दी गई है:आपके ऐप्लिकेशन में ऐसा बिल्ड टाइप मौजूद है जो लाइब्रेरी डिपेंडेंसी के लिए मौजूद नहीं है.
उदाहरण के लिए, आपके ऐप्लिकेशन में "स्टैजिंग" बिल्ड टाइप शामिल है, लेकिन डिपेंडेंसी में सिर्फ़ "डीबग" और "रिलीज़" बिल्ड टाइप शामिल हैं.
ध्यान दें कि अगर लाइब्रेरी डिपेंडेंसी में ऐसा बिल्ड टाइप शामिल है जो आपके ऐप्लिकेशन में नहीं है, तो कोई समस्या नहीं होती. ऐसा इसलिए होता है, क्योंकि प्लग इन कभी भी डिपेंडेंसी से उस तरह का बिल्ड टाइप का अनुरोध नहीं करता.
matchingFallbacks
का इस्तेमाल करके, दिए गए बिल्ड टाइप के लिए वैकल्पिक मैच बताएं, जैसा कि यहां दिखाया गया है:Kotlin
// In the app's build.gradle.kts file. android { buildTypes { getByName("debug") {} getByName("release") {} create("staging") { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks += listOf("debug", "qa", "release") } } }
Groovy
// In the app's build.gradle file. android { buildTypes { debug {} release {} staging { // Specifies a sorted list of fallback build types that the // plugin can try to use when a dependency does not include a // "staging" build type. You may specify as many fallbacks as you // like, and the plugin selects the first build type that's // available in the dependency. matchingFallbacks = ['debug', 'qa', 'release'] } } }
ऐप्लिकेशन और उसकी लाइब्रेरी डिपेंडेंसी, दोनों में मौजूद किसी फ़्लेवर डाइमेंशन के लिए, आपके ऐप्लिकेशन में ऐसे फ़्लेवर शामिल हैं जो लाइब्रेरी में नहीं हैं.
उदाहरण के लिए, आपके ऐप्लिकेशन और उसकी लाइब्रेरी डिपेंडेंसी, दोनों में "टीयर" फ़्लेवर डाइमेंशन शामिल होता है. हालांकि, ऐप्लिकेशन के "टीयर" डाइमेंशन में "मुफ़्त" और "पेड" फ़्लेवर शामिल किए गए हैं. हालांकि, एक ही डाइमेंशन के लिए सिर्फ़ "डेमो" और "पेड" फ़्लेवर शामिल हैं.
ध्यान दें कि अगर किसी फ़्लेवर डाइमेंशन को ऐप्लिकेशन और उसकी लाइब्रेरी डिपेंडेंसी, दोनों में शामिल किया गया है, तो लाइब्रेरी में ऐसा प्रॉडक्ट फ़्लेवर शामिल होने पर कोई समस्या नहीं होती जो आपके ऐप्लिकेशन में शामिल नहीं है. इसकी वजह यह है कि प्लगिन कभी भी डिपेंडेंसी से उस फ़्लेवर का अनुरोध नहीं करता.
ऐप्लिकेशन के "मुफ़्त" प्रॉडक्ट फ़्लेवर के लिए, मिलते-जुलते विकल्प बताने के लिए
matchingFallbacks
का इस्तेमाल करें, जैसा कि यहां दिखाया गया है:Kotlin
// In the app's build.gradle.kts file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions += "tier" productFlavors { create("paid") { dimension = "tier" // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } create("free") { dimension = "tier" // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks += listOf("demo", "trial") } } }
Groovy
// In the app's build.gradle file. android { defaultConfig{ // Don't configure matchingFallbacks in the defaultConfig block. // Instead, specify fallbacks for a given product flavor in the // productFlavors block, as shown below. } flavorDimensions 'tier' productFlavors { paid { dimension 'tier' // Because the dependency already includes a "paid" flavor in its // "tier" dimension, you don't need to provide a list of fallbacks // for the "paid" flavor. } free { dimension 'tier' // Specifies a sorted list of fallback flavors that the plugin // can try to use when a dependency's matching dimension does // not include a "free" flavor. Specify as many // fallbacks as you like; the plugin selects the first flavor // that's available in the dependency's "tier" dimension. matchingFallbacks = ['demo', 'trial'] } } }
लाइब्रेरी डिपेंडेंसी में ऐसा फ़्लेवर डाइमेंशन शामिल है जो आपके ऐप्लिकेशन में नहीं है.
उदाहरण के लिए, किसी लाइब्रेरी डिपेंडेंसी में "minApi" डाइमेंशन के लिए फ़्लेवर शामिल होते हैं, लेकिन आपके ऐप्लिकेशन में सिर्फ़ "टीयर" डाइमेंशन के लिए फ़्लेवर शामिल होते हैं. जब आपको अपने ऐप्लिकेशन का "freeDebug" वर्शन बनाना हो, तो प्लग इन को यह पता नहीं चलता कि डिपेंडेंसी के "minApi23Debug" या "minApi18Debug" वर्शन में से किसका इस्तेमाल करना है.
ध्यान दें कि अगर आपके ऐप्लिकेशन में कोई ऐसा फ़्लेवर डाइमेंशन शामिल है जो लाइब्रेरी डिपेंडेंसी में शामिल नहीं है, तो कोई समस्या नहीं होती. ऐसा इसलिए होता है, क्योंकि प्लग इन सिर्फ़ उन डाइमेंशन के फ़्लेवर से मैच करता है जो डिपेंडेंसी में मौजूद होते हैं. उदाहरण के लिए, अगर किसी डिपेंडेंसी में एबीआई के लिए डाइमेंशन शामिल नहीं है, तो आपके ऐप्लिकेशन का "freeX86Debug" वर्शन, डिपेंडेंसी के "freeDebug" वर्शन का इस्तेमाल करेगा.
defaultConfig
ब्लॉक मेंmissingDimensionStrategy
का इस्तेमाल करके, प्लग इन के लिए डिफ़ॉल्ट फ़्लेवर तय करें, ताकि वह हर उस डाइमेंशन को चुन सके जो मौजूद नहीं है. इस बारे में, यहां दिए गए सैंपल में बताया गया है.productFlavors
ब्लॉक में, अपने चुने गए विकल्पों को बदला भी जा सकता है, ताकि हर फ़्लेवर, मौजूद न होने वाले डाइमेंशन के लिए मैच करने की अलग रणनीति तय कर सके.Kotlin
// In the app's build.gradle.kts file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy("minApi", "minApi18", "minApi23") // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy("abi", "x86", "arm64") } flavorDimensions += "tier" productFlavors { create("free") { dimension = "tier" // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the "minApi" dimension. missingDimensionStrategy("minApi", "minApi23", "minApi18") } create("paid") {} } }
Groovy
// In the app's build.gradle file. android { defaultConfig{ // Specifies a sorted list of flavors that the plugin can try to use from // a given dimension. This tells the plugin to select the "minApi18" flavor // when encountering a dependency that includes a "minApi" dimension. // You can include additional flavor names to provide a // sorted list of fallbacks for the dimension. missingDimensionStrategy 'minApi', 'minApi18', 'minApi23' // Specify a missingDimensionStrategy property for each // dimension that exists in a local dependency but not in your app. missingDimensionStrategy 'abi', 'x86', 'arm64' } flavorDimensions 'tier' productFlavors { free { dimension 'tier' // You can override the default selection at the product flavor // level by configuring another missingDimensionStrategy property // for the 'minApi' dimension. missingDimensionStrategy 'minApi', 'minApi23', 'minApi18' } paid {} } }
ज़्यादा जानकारी के लिए, Android Gradle प्लग-इन डीएसएल रेफ़रंस में matchingFallbacks
और missingDimensionStrategy
देखें.
साइनिंग सेटिंग कॉन्फ़िगर करें
Gradle, रिलीज़ बंडल के APK या AAB को तब तक साइन नहीं करता, जब तक कि आपने इस बंडल के लिए साइन करने का कॉन्फ़िगरेशन साफ़ तौर पर तय न कर दिया हो. अगर आपके पास अब तक साइनिंग पासकोड नहीं है, तो Android Studio का इस्तेमाल करके अपलोड पासकोड और पासकोड स्टोर जनरेट करें.
Gradle के बिल्ड कॉन्फ़िगरेशन का इस्तेमाल करके, रिलीज़ बिल्ड टाइप के लिए हस्ताक्षर करने के कॉन्फ़िगरेशन को मैन्युअल तरीके से कॉन्फ़िगर करने के लिए:
- पासकोड बनाएं. कीस्टोर एक बाइनरी फ़ाइल होती है, जिसमें निजी कुंजियों का एक सेट होता है. आपको अपना कीस्टोर किसी सुरक्षित जगह पर रखना चाहिए.
- निजी कुंजी बनाएं. निजी कुंजी का इस्तेमाल, आपके ऐप्लिकेशन को डिस्ट्रिब्यूशन के लिए साइन करने के लिए किया जाता है. इसे कभी भी ऐप्लिकेशन में शामिल नहीं किया जाता या बिना अनुमति वाले तीसरे पक्षों के साथ शेयर नहीं किया जाता.
-
मॉड्यूल-लेवल की
build.gradle.kts
फ़ाइल में, हस्ताक्षर करने का कॉन्फ़िगरेशन जोड़ें:Kotlin
... android { ... defaultConfig {...} signingConfigs { create("release") { storeFile = file("myreleasekey.keystore") storePassword = "password" keyAlias = "MyReleaseKey" keyPassword = "password" } } buildTypes { getByName("release") { ... signingConfig = signingConfigs.getByName("release") } } }
ग्रूवी
... android { ... defaultConfig {...} signingConfigs { release { storeFile file("myreleasekey.keystore") storePassword "password" keyAlias "MyReleaseKey" keyPassword "password" } } buildTypes { release { ... signingConfig signingConfigs.release } } }
ध्यान दें: अपनी रिलीज़ कुंजी और कीस्टोर के पासवर्ड को बिल्ड फ़ाइल में शामिल करना, सुरक्षा के लिहाज़ से सही नहीं है. इसके बजाय, एनवायरमेंट वैरिएबल से ये पासवर्ड पाने के लिए, बिल्ड फ़ाइल को कॉन्फ़िगर करें या बिल्ड प्रोसेस के दौरान, आपसे ये पासवर्ड मांगे जाएं.
एनवायरमेंट वैरिएबल से ये पासवर्ड पाने के लिए:
Kotlin
storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")
ग्रूवी
storePassword System.getenv("KSTOREPWD") keyPassword System.getenv("KEYPWD")
इसके अलावा, किसी स्थानीय प्रॉपर्टी फ़ाइल से भी पासकोड लोड किया जा सकता है. सुरक्षा से जुड़ी वजहों से, इस फ़ाइल को सोर्स कंट्रोल में न जोड़ें. इसके बजाय, हर डेवलपर के लिए इसे स्थानीय तौर पर सेट अप करें. ज़्यादा जानने के लिए, अपनी बिल्ड फ़ाइलों से हस्ताक्षर करने की जानकारी हटाना लेख पढ़ें.
यह प्रोसेस पूरी करने के बाद, अपने ऐप्लिकेशन को डिस्ट्रिब्यूट किया जा सकता है और उसे Google Play पर पब्लिश किया जा सकता है.
चेतावनी: अपने कीस्टोर और निजी कुंजी को किसी सुरक्षित जगह पर रखें और पक्का करें कि आपके पास इनका सुरक्षित बैकअप हो. अगर Play ऐप्लिकेशन साइनिंग का इस्तेमाल किया जा रहा है और आपका अपलोड पासकोड खो जाता है, तो Play Console का इस्तेमाल करके रीसेट करने का अनुरोध किया जा सकता है. अगर अगस्त 2021 से पहले बनाए गए ऐप्लिकेशन को 'Play ऐप्लिकेशन साइनिंग' के बिना पब्लिश किया जा रहा है और आपका ऐप्लिकेशन साइनिंग पासकोड खो जाता है, तो आपके पास अपने ऐप्लिकेशन के लिए कोई अपडेट पब्लिश करने का विकल्प नहीं होगा. ऐसा इसलिए, क्योंकि ऐप्लिकेशन के सभी वर्शन को एक ही पासकोड से साइन करना ज़रूरी है.
Wear OS ऐप्लिकेशन को हस्ताक्षर करना
Wear OS ऐप्लिकेशन पब्लिश करते समय, स्मार्टवॉच के APK और फ़ोन के APK, दोनों पर एक ही कुंजी से हस्ताक्षर किए जाने चाहिए. हालांकि, फ़ोन के लिए APK बनाना ज़रूरी नहीं है. Wear OS ऐप्लिकेशन को पैकेज करने और उन पर हस्ताक्षर करने के बारे में ज़्यादा जानने के लिए, Wear ऐप्लिकेशन को पैकेज करना और उन्हें उपलब्ध कराना लेख पढ़ें.