Android डेवलपमेंट में Build Variant, build type और product flavor का एक संयोजन है जो यह निर्धारित करता है कि APK या AAB कैसे बनाया जाएगा: किन पैरामीटरों, संसाधनों और कोड के साथ। प्रत्येक बिल्ड वेरिएंट अपने स्वयं के applicationId, साइनिंग कुंजियों और शामिल निर्भरताओं के साथ एक अलग Gradle कॉन्फ़िगरेशन का प्रतिनिधित्व करता है। Google Android Developers, 2025 के अनुसार, Build Variants का सही कॉन्फ़िगरेशन प्रत्येक वेरिएंट के लिए अनावश्यक संसाधनों को हटाकर बिल्ड समय को 40% तक कम करता है। बिल्ड वेरिएंट सिस्टम आधुनिक Android प्रोजेक्ट्स में कॉन्फ़िगरेशन प्रबंधन की नींव है।
मुख्य बिंदु
Build Variant एक Build Type और एक Product Flavor के संयोजन का परिणाम है। यदि प्रोजेक्ट में कोई Product Flavors परिभाषित नहीं हैं, तो Build Variant Build Type से मेल खाता है। Gradle स्वचालित रूप से सभी FlavorDimensions, Product Flavors और Build Types के कार्टेशियन उत्पाद के रूप में वेरिएंट का पूरा सेट उत्पन्न करता है। उदाहरण के लिए, free/paid flavors और debug/release types के लिए 4 वेरिएंट बनाए जाएंगे: freeDebug, freeRelease, paidDebug, paidRelease।
प्रत्येक Build Variant को <Flavor><Type> प्रारूप में अपना नाम मिलता है जिसमें flavor बड़े अक्षर से शुरू होता है। Gradle इस वेरिएंट के लिए अलग-अलग कार्य उत्पन्न करता है: assembleFreeDebug, installFreeDebug, bundleFreeRelease। Android Studio में, Build Variants पैनल (View → Tool Windows → Build Variants) के माध्यम से वेरिएंट के बीच स्विच करना उपलब्ध है। वेरिएंट चुनने से प्रभावित होता है कि कौन सा कोड संकलित होता है, कौन से संसाधन शामिल होते हैं, और कौन सा APK/AAB तैयार होता है।
Build Variants सिस्टम तीन मुख्य कार्यों को हल करता है: विभिन्न वातावरणों (dev/staging/production) के लिए कॉन्फ़िगरेशन को अलग करना, ऐप के कई संस्करण (free/paid) बनाना, और बिल्ड का A/B परीक्षण करना। Build Variants के बिना, डेवलपर्स को मैन्युअल रूप से फ़्लैग और कॉन्फ़िगरेशन बदलने होंगे, जिससे मानवीय त्रुटियाँ होती हैं। Gradle Inc., 2024 के एक अध्ययन के अनुसार, Build Variants लागू करने से तीन या अधिक परिनियोजन वातावरण वाले प्रोजेक्ट्स में बिल्ड त्रुटियाँ 60% कम होती हैं।
AGP (Android Gradle Plugin) कॉन्फ़िगरेशन चरण में सभी संयोजनों की गणना करता है। यदि किसी प्रोजेक्ट में क्रमशः दो और तीन flavors के साथ दो आयाम हैं, तो Gradle 2 × 2 × 3 = 12 संयोजन बनाएगा, जो Build Types की संख्या (आमतौर पर 2) से गुणा होते हैं। प्रत्येक संयोजन को एक अद्वितीय नाम और कार्यों का सेट मिलता है। AGP स्वचालित रूप से प्रत्येक वेरिएंट के लिए source set जोड़ता है: src/freeDebug/, src/paidRelease/, साथ ही सामान्यीकृत src/free/ और src/debug/। संसाधन पढ़ने की प्राथमिकता: variant → flavor → type → main।
// उदाहरण: 4 Build Variants
// flavorDimensions "version", "server"
// version: demo, prod
// server: mock, live
// buildTypes: debug, release
// कुल: 2 × 2 × 2 = 8 वेरिएंट
android {
flavorDimensions "version", "server"
productFlavors {
demo { dimension "version" }
prod { dimension "version" }
mock { dimension "server" }
live { dimension "server" }
}
}
Build Type यह निर्धारित करता है कि एप्लिकेशन कैसे बनाया जाए — डीबग जानकारी के साथ या बिना, ऑप्टिमाइज़ेशन के साथ या बिना, किस साइनिंग के साथ। Product Flavor यह निर्धारित करता है कि क्या बनाया जाए — उत्पाद का कौन सा संस्करण। Build Type एक बिल्ड तंत्र है (debug, release, staging)। Product Flavor एक उत्पाद वेरिएंट है (free, paid, enterprise, demo)। दोनों अवधारणाएँ ऑर्थोगोनल हैं: किसी भी Build Type को किसी भी Product Flavor पर लागू किया जा सकता है।
डिफ़ॉल्ट Build Types में debug (debuggable=true, minification=false, signing=debug.keystore) और release (debuggable=false, minification=true, signing=production.keystore) शामिल हैं। डिफ़ॉल्ट Product Flavor एक, अनाम है (प्रभावी रूप से main source set)। डेवलपर्स अपने स्वयं के Build Types (जैसे, “staging” जिसमें debuggable=true और minification=true है) और कितने भी Product Flavors जोड़ सकते हैं। एक और अंतर यह है कि Build Types को आयामों में समूहित नहीं किया जा सकता, जबकि Product Flavors को किया जा सकता है।
मुख्य व्यावहारिक अंतर: defaultConfig build.gradle में सभी Variants पर लागू होता है लेकिन productFlavors और buildTypes में ओवरराइड किया जा सकता है। buildType में जोड़ा गया BuildConfigField उस प्रकार के सभी flavors में दिखाई देता है, जबकि productFlavor में जोड़ा गया उस flavor के सभी प्रकारों में दिखाई देता है। यदि कोई फ़ील्ड दोनों में परिभाषित है, तो buildType को प्राथमिकता मिलती है (इसे श्रृंखला में अंतिम रूप से लागू किया जाता है)।
| विशेषता | Build Type | Product Flavor |
|---|---|---|
| उद्देश्य | कैसे बनाना है | क्या बनाना है |
| उदाहरण | debug, release, staging | free, paid, demo, enterprise |
| डिफ़ॉल्ट | debug + release | एक (main) |
| Source Set | src/debug/, src/release/ | src/free/, src/paid/ |
| आयाम | नहीं | flavorDimensions |
| आवेदन क्रम | flavor के बाद, ओवरराइड करता है | defaultConfig के बाद |
| BuildConfigField | flavor को ओवरराइड करता है | defaultConfig को ओवरराइड करता है |
Build Variants कॉन्फ़िगरेशन मॉड्यूल-स्तरीय build.gradle फ़ाइल के android ब्लॉक में किया जाता है। पहले buildTypes को उनके पैरामीटर के साथ घोषित किया जाता है, फिर flavorDimensions और productFlavors। Gradle इन घोषणाओं के आधार पर स्वचालित रूप से वेरिएंट बनाता है। प्रत्येक वेरिएंट मॉड्यूल के defaultConfig को इनहेरिट करता है, निर्दिष्ट फ़ील्ड को ओवरराइड करता है। घोषणा क्रम प्राथमिकता को प्रभावित करता है: buildTypes productFlavors के बाद लागू होते हैं।
Gradle स्क्रिप्ट में किसी विशिष्ट Build Variant तक पहुँचने के लिए, android.applicationVariants (app मॉड्यूल के लिए) या android.libraryVariants (लाइब्रेरी मॉड्यूल के लिए) का उपयोग करें। यह एक संग्रह है जिसे कॉन्फ़िगरेशन रनटाइम पर प्रत्येक वेरिएंट के कॉन्फ़िगरेशन को संशोधित करने के लिए पुनरावृत्त किया जा सकता है। उदाहरण के लिए, आप “demo” शब्द वाले सभी वेरिएंट के लिए प्रोग्रामेटिक रूप से buildConfigField जोड़ सकते हैं।
Android Gradle Plugin 8.x ने onVariants के लिए समर्थन जोड़ा — lambdas के माध्यम से वेरिएंट कॉन्फ़िगर करने के लिए एक स्वच्छ API। पुराने API (variantOutput, variantFilter) को deprecated चिह्नित किया गया है। लाइब्रेरी मॉड्यूल के लिए onEach के साथ onVariants का उपयोग करने की अनुशंसा की जाती है। variantOutput से onVariants में माइग्रेट करना AGP को 7.x से 8.x में अपग्रेड करते समय अनुशंसित कदम है।
android {
buildTypes {
debug {
debuggable true
minification false
signingConfig signingConfigs.debug
}
release {
debuggable false
minification true
proguardFiles "proguard-rules.pro"
signingConfig signingConfigs.release
}
staging {
debuggable true
minification true
versionNameSuffix "-staging"
}
}
flavorDimensions "tier", "region"
productFlavors {
free { dimension "tier" }
paid { dimension "tier" }
us { dimension "region" }
eu { dimension "region" }
}
}
android.onVariants { variant ->
if (variant.name.contains("Demo")) {
variant.setEnabled(false)
}
}
प्रत्येक Build Variant को source sets का अपना पदानुक्रम मिलता है — स्रोत कोड, संसाधनों और मेनिफेस्ट वाली निर्देशिकाएँ। एक source set src/<variantName>/ पर स्थित होता है (जैसे, src/freeDebug/) और इसमें java/, res/, AndroidManifest.xml, assets/ हो सकते हैं। यदि कोई फ़ाइल वेरिएंट के source set में मौजूद है, तो वह मुख्य source set (src/main/) से उसी नाम की फ़ाइल को ओवरराइड करती है। संसाधनों के लिए, प्रतिस्थापन के बजाय विलय होता है — सिस्टम सभी सक्रिय source sets से संसाधनों को मर्ज करता है, वेरिएंट-विशिष्ट को प्राथमिकता देता है।
Build Variant के लिए source sets एक श्रृंखला में बनाए जाते हैं: src/main/ → src/flavor/ → src/type/ → src/flavorType/। उदाहरण के लिए, paidRelease के लिए, पहले main लागू होता है, फिर paid, फिर release, फिर paidRelease। प्रत्येक बाद वाला source set पिछले को ओवरराइड करता है। इसका मतलब है कि src/release/res/values/strings.xml src/paid/ से समान स्ट्रिंग्स को ओवरराइड करेगा, लेकिन src/paidRelease/res/ की और भी अधिक प्राथमिकता है।
वेरिएंट के लिए source sets का उपयोग संसाधनों को अनुकूलित करने का अनुशंसित तरीका है। कोड में BuildConfig.FLAVOR की जाँच करने और तर्क को शाखाबद्ध करने के बजाय, आप बस विभिन्न फ़ाइलों को विभिन्न source sets में रख सकते हैं। उदाहरण के लिए, free और paid संस्करणों के आइकन क्रमशः src/free/res/ और src/paid/res/ में जाते हैं, और विभिन्न अनुमतियों वाला AndroidManifest src/free/AndroidManifest.xml और src/paid/AndroidManifest.xml में जाता है। यह साफ़, तेज़ (संसाधन संकलित होते हैं, रनटाइम पर जाँच नहीं की जाती) और अधिक सुरक्षित है (आप कोड बग के कारण गलती से मुफ़्त संस्करण में भुगतान कार्यक्षमता शामिल नहीं कर सकते)।
मल्टी-मॉड्यूल प्रोजेक्ट्स में, प्रत्येक मॉड्यूल (लाइब्रेरी) के अपने Build Variants हो सकते हैं। AGP स्वचालित रूप से वेरिएंट को सिंक्रोनाइज़ करता है: यदि app मॉड्यूल paidRelease बनाता है, तो सभी आश्रित लाइब्रेरीज़ भी paidRelease के अनुरूप अपने वेरिएंट में बनाई जाती हैं। समस्या तब उत्पन्न होती है जब लाइब्रेरी में product flavors नहीं हैं लेकिन app मॉड्यूल में हैं — तब लाइब्रेरी एक बार बनाई जाती है (प्रकार के आधार पर release या debug)।
लाइब्रेरी मॉड्यूल के लिए, Build Variant डिफ़ॉल्ट रूप से app मॉड्यूल के Build Type से मेल खाता है, क्योंकि लाइब्रेरी में product flavors नहीं होते। यदि लाइब्रेरी को app मॉड्यूल के flavor के अनुकूल होने की आवश्यकता है, तो लाइब्रेरी में समान flavorDimensions और productFlavors घोषित किए जाने चाहिए। AGP नाम के सटीक मिलान से flavors का मिलान करता है। Gradle रूट प्रोजेक्ट में subprojects या Convention Plugins का उपयोग करके बिल्ड कॉन्फ़िगरेशन के माध्यम से flavors को सिंक्रोनाइज़ करने की अनुशंसा करता है।
AGP 8.1 से शुरू करके, लाइब्रेरीज़ multiple variants प्रकाशित कर सकती हैं — सभी लाइब्रेरी वेरिएंट को एक साथ maven रिपॉजिटरी में प्रकाशित करना। यह समस्या हल करता है जब app मॉड्यूल भुगतान flavor का उपयोग करता है लेकिन लाइब्रेरी केवल मुफ़्त के लिए प्रकाशित होती है। Multiple variants publishing (MVP) आश्रित प्रोजेक्ट को स्वचालित रूप से आवश्यक वेरिएंट चुनने की अनुमति देता है। MVP सक्षम करने के लिए, लाइब्रेरी के build.gradle में publishing { multipleVariants { ... } } जोड़ें।
कभी-कभी कुछ Build Variants को अक्षम करना आवश्यक होता है — उदाहरण के लिए, यदि mockRelease संयोजन का कोई अर्थ नहीं है (मॉक सर्वर को प्रोडक्शन में नहीं जाना चाहिए)। Gradle variantFilter प्रदान करता है — एक DSL ब्लॉक जहाँ आप प्रत्येक वेरिएंट के गुणों की जाँच कर सकते हैं और setIgnore(true) के माध्यम से इसे अक्षम कर सकते हैं। VariantFilter कार्य निर्माण से पहले, कॉन्फ़िगरेशन चरण में लागू होता है, इसलिए अक्षम वेरिएंट assemble और install कार्य उत्पन्न नहीं करता।
फ़िल्टरिंग बिल्ड को गति देने के लिए भी उपयोगी है। यदि किसी प्रोजेक्ट में 8 वेरिएंट हैं लेकिन डेवलपर केवल एक पर काम कर रहा है, तो शेष 7 वेरिएंट अभी भी कॉन्फ़िगरेशन से गुज़रते हैं। variantFilter का उपयोग करते समय, अक्षम वेरिएंट कार्य नहीं बनाते, जिससे 6+ flavor आयामों वाले प्रोजेक्ट्स के लिए कॉन्फ़िगरेशन समय 30-50% कम हो जाता है। CI/CD में, आप कमांड लाइन पैरामीटर -PbuildOnly=paidRelease के माध्यम से डायनामिक रूप से वेरिएंट फ़िल्टर कर सकते हैं।
android {
variantFilter { variant ->
// release और production के लिए demo को अक्षम करने हेतु mock को बंद करें
def names = variant.flavors*.name
def isMock = names.contains("mock")
def isDemo = names.contains("demo")
def isRelease = variant.buildType.name == "release"
if ((isMock && isRelease) || (isDemo && !isMock)) {
variant.setIgnore(true)
}
}
}
// पैरामीटर के माध्यम से डायनामिक फ़िल्टरिंग
if (project.hasProperty("buildOnly")) {
def target = project.property("buildOnly")
android.variantFilter { variant ->
variant.setIgnore(variant.name != target)
}
}
अक्सर पूछे जाने वाले प्रश्न
कोई सीमा नहीं है, लेकिन Gradle सभी flavors और प्रकारों का कार्टेशियन उत्पाद बनाता है। यदि आपके पास 3 आयाम हैं जिनमें प्रत्येक में 3 flavors हैं और 3 build types हैं, तो आपको 27 वेरिएंट मिलते हैं। बहुत अधिक वेरिएंट कॉन्फ़िगरेशन को धीमा कर देते हैं। एक मॉड्यूल में 10-12 से अधिक वेरिएंट न रखने की अनुशंसा की जाती है।
flavorDimensions Product Flavors को स्वतंत्र अक्षों में समूहित करते हैं। उदाहरण के लिए, “tier” आयाम (free, paid) और “region” आयाम (us, eu)। आयामों के बिना, सभी flavors एक अक्ष से संबंधित होते हैं, और Gradle सभी में से केवल एक flavor का चयन करेगा (आप free+us और paid+eu को अलग-अलग वेरिएंट के रूप में नहीं रख सकते)।
productFlavor या buildType ब्लॉक में, applicationId निर्दिष्ट करें। उदाहरण के लिए, मुफ़्त संस्करण के लिए: free { applicationId “com.example.app.free” }। मेनिफेस्ट में, ${applicationId} का उपयोग करें — Gradle स्वचालित रूप से मान प्रतिस्थापित करेगा। यह दोनों वेरिएंट को एक डिवाइस पर स्थापित करने की अनुमति देता है।
iOS में, Build Variants का समतुल्य Scheme + Configuration का संयोजन है। Xcode Schemes को विभिन्न पैरामीटर के साथ Debug/Release कॉन्फ़िगरेशन के माध्यम से कॉन्फ़िगर किया जाता है। कई संस्करणों (free/paid) के लिए, Build Configurations और Preprocessor Macros का उपयोग किया जाता है। Android में, अवधारणा अधिक औपचारिक है और Gradle में निर्मित है।
हाँ, प्रत्येक वेरिएंट का APK आकार अलग हो सकता है। Debug बिल्ड में डीबग जानकारी, SDK और असमर्थित संसाधन शामिल होते हैं। minification और resource shrinking वाले Release बिल्ड न्यूनतम आकार उत्पन्न करते हैं। Product Flavor भी आकार को प्रभावित करता है: भुगतान लाइब्रेरी के बिना मुफ़्त संस्करण उन लाइब्रेरी के आकार से भुगतान संस्करण से छोटा होगा।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें