Product Flavor: यह क्या है, Gradle में कॉन्फ़िगरेशन और उदाहरण

लेखक: IT Sectr प्रकाशित: 2026-05-30 पढ़ने का समय: 9 मिनट

Android डेवलपमेंट में Product Flavor एक Gradle तंत्र है जो साझा कोड बेस से एक ही एप्लिकेशन के कई वेरिएंट बनाने की अनुमति देता है। प्रत्येक flavor का अपना applicationId, संसाधन, निर्भरताएँ और कार्यक्षमता हो सकती है — उदाहरण के लिए, मुफ्त और भुगतान वाले संस्करण। Google Android Developers, 2025 के अनुसार, Product Flavors Build Variants प्रणाली का हिस्सा हैं और flavorDimensions के माध्यम से Build Types के साथ संयुक्त होते हैं। Google Play पर कई ऐप संस्करण प्रकाशित करने का यह मानक तरीका है।

मुख्य बातें

  • Product Flavor — अद्वितीय applicationId, संसाधनों और कोड के साथ एक उत्पाद वेरिएंट।
  • Flavor Dimensions बहु-आयामी कॉन्फ़िगरेशन के लिए flavors को स्वतंत्र अक्षों में समूहित करते हैं।
  • Source sets एक flavor के लिए मुख्य संसाधनों को ओवरराइड करते हैं: आइकन, स्ट्रिंग्स, मेनिफ़ेस्ट।
  • Gradle स्वचालित रूप से flavor + build type के प्रत्येक संयोजन के लिए Build Variant उत्पन्न करता है।
  • Google Play कई flavors को अलग-अलग ऐप या विभिन्न कॉन्फ़िगरेशन वाले एकल ऐप के रूप में प्रकाशित करने का समर्थन करता है।

Product Flavor क्या है?

Product Flavor android.productFlavors ब्लॉक में एक Gradle कॉन्फ़िगरेशन है जो उत्पाद के वेरिएंट का वर्णन करता है। प्रत्येक flavor applicationId, versionName, versionCode, minSdkVersion, targetSdkVersion, signingConfig और defaultConfig के अन्य मापदंडों को ओवरराइड कर सकता है। Product Flavors की मात्रा की कोई सीमा नहीं है: एक प्रोजेक्ट में 2, 5 या 10 flavors हो सकते हैं — Gradle सभी संयोजनों को संभालता है।

Product Flavor codebase reuse की समस्या को हल करता है — जब एक ही रिपॉजिटरी से कई अलग-अलग एप्लिकेशन बनाने की आवश्यकता होती है। विशिष्ट परिदृश्य: विज्ञापनों के साथ मुफ्त संस्करण और उनके बिना भुगतान वाला संस्करण; सीमित कार्यक्षमता वाला डेमो संस्करण; कॉर्पोरेट और उपभोक्ता संस्करण; विभिन्न ग्राहकों के लिए white-label ऐप। Product Flavors के बिना, प्रत्येक संस्करण को एक अलग प्रोजेक्ट में बनाए रखना होगा, जिससे 60-70% कोड दोहराव होता है।

ऐतिहासिक रूप से, Product Flavors Android Gradle Plugin 0.9 (2013) में ant कॉन्फ़िगरेशन के प्रतिस्थापन के रूप में दिखाई दिए। इससे पहले, डेवलपर विभिन्न संस्करणों के लिए अलग-अलग प्रोजेक्ट या बिल्ड से पहले मैन्युअल संसाधन प्रतिस्थापन का उपयोग करते थे। AGP में flavors के शामिल होने ने दृष्टिकोण को एकीकृत किया और इसे मानक बना दिया। JetBrains, 2024 के एक सर्वेक्षण के अनुसार, कई संस्करणों वाली 78% Android परियोजनाएँ Product Flavors का उपयोग करती हैं, जबकि शेष BuildConfig या reflection के माध्यम से मैन्युअल स्विचिंग का उपयोग करती हैं।

Product Flavor बनाम Build Type

Build Type बिल्ड प्रक्रिया का प्रबंधन करता है (डीबगिंग के साथ debug, अनुकूलन के साथ release)। Product Flavor बिल्ड सामग्री का प्रबंधन करता है (भुगतान सुविधाओं के बिना free, उनके साथ paid)। Build Type एक बुनियादी ढाँचा सेटिंग है, Product Flavor एक उत्पाद सेटिंग है। दोनों अवधारणाएँ ऑर्थोगोनल हैं: free flavor की debug बिल्ड free flavor की release बिल्ड से केवल संकलन मापदंडों में भिन्न होती है, कार्यक्षमता में नहीं। Product Flavor का उपयोग डीबगर को अक्षम करने के लिए नहीं किया जा सकता — यह Build Type का काम है।

Flavor Dimensions: मापों का संगठन

मापों का क्रम और प्राथमिकता

Flavor Dimensions Product Flavors को स्वतंत्र श्रेणियों में समूहित करने का एक तंत्र है। यदि किसी ऐप में मुफ्त/भुगतान वाला संस्करण और अलग से अमेरिकी/यूरोपीय क्षेत्र है, तो flavors को दो आयामों में समूहित किया जाता है: "tier" (free, paid) और "region" (us, eu)। Gradle आयामों का कार्टेशियन गुणनफल बनाता है: freeUs, freeEu, paidUs, paidEu — 4 वेरिएंट। आयामों के बिना, Gradle सभी चार flavors को एक ही तल के रूप में मानेगा, और केवल एक का चयन किया जा सकता है।

आयाम flavorDimensions ब्लॉक में एक स्ट्रिंग या स्ट्रिंग्स की सूची के रूप में घोषित किए जाते हैं। आयामों का क्रम source sets की प्राथमिकता को प्रभावित करता है: पहले आयाम की उच्चतम प्राथमिकता होती है। यदि आयाम A (tier) पहले निर्दिष्ट किया गया है, तो संसाधन विरोध के मामले में src/free/, src/us/ को ओवरराइड करेगा। क्रम यह भी प्रभावित करता है कि Variant का नाम कैसे बनता है: पहले पहले आयाम के flavors आते हैं, फिर दूसरे के, फिर Build Type: freeUsDebug।

आयामों की संख्या सीमित नहीं है, लेकिन प्रत्येक नया आयाम Build Variants की संख्या को गुणा करता है। 4 आयामों (प्रत्येक में 2 flavors) और 2 build types वाले प्रोजेक्ट के लिए, आपको 2 × 2 × 2 × 2 × 2 = 32 वेरिएंट मिलते हैं। व्यावहारिक सीमा 3 आयाम है (अधिकतम 8-12 वेरिएंट)। इससे अधिक होने पर, Gradle कॉन्फ़िगरेशन धीमा हो जाता है और Android Studio में Build Variants पैनल अपठनीय हो जाता है।

groovy
android {
    flavorDimensions "tier", "api"

    productFlavors {
        free {
            dimension "tier"
            applicationId "com.example.app.free"
            versionNameSuffix "-free"
        }
        paid {
            dimension "tier"
            applicationId "com.example.app.paid"
        }
        minApi21 {
            dimension "api"
            minSdk 21
        }
        minApi26 {
            dimension "api"
            minSdk 26
        }
    }
}

// परिणाम: freeMinApi21, freeMinApi26, paidMinApi21, paidMinApi26
// प्रत्येक × debug/release = 8 Build Variants

build.gradle में Product Flavors बनाना

Product Flavors के लिए Kotlin DSL

Product Flavor बनाने के लिए, android के अंदर एक productFlavors ब्लॉक जोड़ना होगा, flavor का नाम और उसके पैरामीटर निर्दिष्ट करने होंगे। न्यूनतम flavor घोषणा नाम और आयाम है। अन्य सभी पैरामीटर defaultConfig से विरासत में मिलते हैं और ओवरराइड किए जा सकते हैं। Flavor पूरी तरह से defaultConfig प्राप्त करता है, जिसमें applicationId, versionCode, testInstrumentationRunner शामिल हैं।

प्रत्येक flavor applicationId को ओवरराइड कर सकता है — यह एक ही डिवाइस पर एक साथ कई ऐप संस्करण स्थापित करने की अनुमति देता है। उदाहरण के लिए, मुफ्त संस्करण com.example.app.free होगा, भुगतान वाला — com.example.app.paid। यदि applicationId ओवरराइड नहीं किया गया है, तो सभी flavors का एक ही पहचानकर्ता होगा, और उन्हें एक साथ स्थापित नहीं किया जा सकता। applicationId को मेनिफ़ेस्ट में पैकेज से मेल खाना चाहिए (जब तक कि applicationIdSuffix का उपयोग न किया गया हो)।

AGP 8+ build.gradle के लिए Groovy के बजाय Kotlin DSL का उपयोग करने की सलाह देता है। Kotlin DSL कॉन्फ़िगरेशन तक type-safe पहुँच प्रदान करता है: IDE पैरामीटर नाम सुझाता है, संकलन समय पर प्रकारों की जाँच करता है और त्रुटियों को हाइलाइट करता है। Product Flavors के लिए Groovy से Kotlin DSL में माइग्रेशन में आमतौर पर उद्धरणों को कोष्ठक से बदलना और प्रकार जोड़ना शामिल है। AGP पिछड़ा-संगत है — दोनों सिंटैक्स एक ही प्रोजेक्ट में समानांतर रूप से काम करते हैं।

kotlin
// build.gradle.kts — Kotlin DSL
android {
    flavorDimensions += "tier"

    productFlavors {
        register("free") {
            dimension = "tier"
            applicationId = "com.example.app.free"
            versionNameSuffix = "-free"
            buildConfigField("boolean", "IS_PREMIUM", "false")
        }
        register("paid") {
            dimension = "tier"
            applicationId = "com.example.app.paid"
            versionNameSuffix = "-paid"
            buildConfigField("boolean", "IS_PREMIUM", "true")
        }
    }
}

विभिन्न flavors के लिए संसाधन और कोड

प्रत्येक Product Flavor अपना स्वयं का source set बनाता है — एक src/<flavorName>/ निर्देशिका। इस निर्देशिका में ओवरराइड किए गए संसाधन, स्रोत फ़ाइलें और मेनिफ़ेस्ट हो सकते हैं। Flavor source set main के ऊपर एक ओवरले के रूप में कार्य करता है: src/free/res/ से फ़ाइलें समान नामों वाली src/main/res/ से फ़ाइलों को ओवरराइड करती हैं। यह मुख्य कोड को संशोधित किए बिना प्रत्येक flavor के लिए अलग-अलग स्ट्रिंग्स, आइकन, रंग और लेआउट रखने की अनुमति देता है।

Java/Kotlin क्लास को ओवरराइड करने के लिए दो दृष्टिकोण हैं: flavor-विशिष्ट कार्यान्वयन (प्रत्येक flavor में एक सार वर्ग को लागू करना) और BuildConfig फ़ील्ड (कोड में शाखाकरण)। पहला दृष्टिकोण अधिक स्वच्छ है: आप main में एक इंटरफ़ेस या सार वर्ग परिभाषित करते हैं, और src/free/ और src/paid/ में ठोस कार्यान्वयन। बिल्ड के दौरान, केवल वर्तमान flavor का कार्यान्वयन संकलित किया जाता है। यह एक साथ लाभ प्रदान करता है: छोटा APK आकार (भुगतान कोड मुफ्त संस्करण में नहीं जाता) और सुरक्षा (गलती से भुगतान फ़ंक्शन को कॉल करना असंभव है)।

Flavor source set में AndroidManifest.xml प्रतिस्थापित नहीं करता बल्कि मुख्य मेनिफ़ेस्ट के साथ मर्ज होता है। मर्जिंग Android नियमों का पालन करती है: एक ही तत्व में डुप्लिकेट विशेषताएँ ओवरराइड की जाती हैं, अद्वितीय जोड़ी जाती हैं। उदाहरण के लिए, यदि मुख्य मेनिफ़ेस्ट INTERNET अनुमति घोषित करता है और free नहीं करता, तो इंटरनेट अनुमति बनी रहती है। हालाँकि, tools:node="replace" किसी विशिष्ट flavor के लिए पूरे मेनिफ़ेस्ट ब्लॉक को बदलने की अनुमति देता है। यह तब उपयोगी होता है जब विभिन्न flavors को अलग-अलग अनुमतियों की आवश्यकता होती है (भुगतान संस्करण के लिए SD कार्ड लेखन, मुफ्त के लिए कैमरा)।

xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:label="Free App"
        tools:replace="android:label">
    </application>
</manifest>

उदाहरण: ऐप के मुफ्त और भुगतान वाले संस्करण

एक विशिष्ट परिदृश्य पर विचार करें: free — विज्ञापनों और बुनियादी सुविधाओं वाला संस्करण, paid — विज्ञापनों के बिना, विस्तारित कार्यक्षमता वाला। मुफ्त संस्करण के लिए, applicationId "com.example.app.free" पर सेट किया गया है, भुगतान वाले के लिए — "com.example.app.paid"। दोनों संस्करण एक ही डिवाइस पर एक साथ स्थापित किए जा सकते हैं, क्योंकि applicationId Android सिस्टम में एप्लिकेशन का अद्वितीय पहचानकर्ता है।

आर्किटेक्चरल रूप से, पृथक्करण इंटरफ़ेस + flavor कार्यान्वयन के माध्यम से बनाया गया है। मुख्य source set में, PaymentService इंटरफ़ेस घोषित किया गया है। src/free/ में, एक कार्यान्वयन है जो AdMob के माध्यम से भुगतान से पहले एक विज्ञापन दिखाता है। src/paid/ में — एक कार्यान्वयन जो सीधे भुगतान गेटवे पर जाता है। PaymentService का उपयोग करने वाला कोड नहीं जानता कि कौन सा कार्यान्वयन लोड किया गया है — यह संकलन समय पर हल किया जाता है। यह दृष्टिकोण गारंटी देता है कि सदस्यता प्रबंधन कोड मुफ्त संस्करण में नहीं आएगा, भले ही डेवलपर गलती से इसे कॉल कर दे।

निर्भरताओं को शामिल/बहिष्कृत करने के कारण विभिन्न flavors के लिए APK आकार 5-15 MB तक भिन्न हो सकता है। किसी विशिष्ट flavor से लाइब्रेरी को बहिष्कृत करने के लिए, build.gradle में flavor-विशिष्ट निर्भरताएँ का उपयोग करें: freeImplementation 'com.google.android.gms:play-services-ads:23.0.0'। यह निर्भरता केवल मुफ्त वेरिएंट के लिए जोड़ी जाएगी और भुगतान संस्करण का आकार नहीं बढ़ाएगी। साझा निर्भरताओं के लिए, implementation का उपयोग करें — सभी flavors उन्हें शामिल करते हैं।

kotlin
// src/main/kotlin/com/example/payment/PaymentService.kt
interface PaymentService {
    fun processOrder(amount: Double, callback: (PaymentResult) -> Unit)
}

// src/free/kotlin/.../FreePaymentService.kt
class FreePaymentService : PaymentService {
    override fun processOrder(amount: Double, callback: (PaymentResult) -> Unit) {
        AdManager.showInterstitial {
            PaymentGateway.charge(amount, callback)
        }
    }
}

// src/paid/kotlin/.../PaidPaymentService.kt
class PaidPaymentService : PaymentService {
    override fun processOrder(amount: Double, callback: (PaymentResult) -> Unit) {
        PaymentGateway.charge(amount, callback)
    }
}

बहु-मॉड्यूल परियोजनाओं में Product Flavor

बहु-मॉड्यूल परियोजनाओं में, लाइब्रेरी मॉड्यूल में अपने स्वयं के Product Flavors नहीं हो सकते हैं, जो एक समस्या पैदा करता है: लाइब्रेरी एक बार (release के रूप में) बनाई जाती है, जबकि flavor वाला ऐप मॉड्यूल संबंधित वेरिएंट के साथ लाइब्रेरी की अपेक्षा करता है। AGP 8.1 से शुरू करके, लाइब्रेरी publishing.multipleVariants ब्लॉक के माध्यम से एकाधिक वेरिएंट प्रकाशित कर सकती हैं — यह लाइब्रेरी के सभी flavor वेरिएंट को एक maven रिपॉजिटरी में प्रकाशित करने की अनुमति देता है, और ऐप मॉड्यूल स्वचालित रूप से सही वेरिएंट का चयन करेगा।

एक वैकल्पिक दृष्टिकोण लाइब्रेरी में वही flavorDimensions और productFlavors घोषित करना है जो ऐप मॉड्यूल में हैं। AGP स्वचालित रूप से एक आयाम के भीतर सटीक नाम मिलान द्वारा flavors का मिलान करता है। यदि लाइब्रेरी में flavor का नाम ऐप में नाम से मेल खाता है, तो AGP सुसंगत वेरिएंट बनाएगा। रखरखाव में आसानी के लिए, सामान्य flavor परिभाषाओं को Convention Plugin में निकालने की अनुशंसा की जाती है — एक Gradle प्लगइन जो प्रोजेक्ट के सभी मॉड्यूल पर लागू होता है।

प्रकाशन के लिए नहीं बनाई गई लाइब्रेरी (आंतरिक मॉड्यूल) के लिए, रूट प्रोजेक्ट के build.gradle के माध्यम से flavors को सिंक्रनाइज़ करना पर्याप्त है। Gradle subprojects विधि प्रदान करता है, जो सभी उप-प्रोजेक्ट्स पर कॉन्फ़िगरेशन लागू करने की अनुमति देता है। हालाँकि, ध्यान रखें कि subprojects में बहुत अधिक कॉन्फ़िगरेशन कॉन्फ़िगरेशन चरण को धीमा कर देता है। Convention Plugins का उपयोग करने की अनुशंसा की जाती है — वे एक बार संकलित होते हैं और पुनः उपयोग किए जाते हैं, जिससे कॉन्फ़िगरेशन समय 15-30% कम हो जाता है।

अक्सर पूछे जाने वाले प्रश्न

कितने Product Flavors बनाए जा सकते हैं?

मात्रा की कोई सीमा नहीं है, लेकिन प्रत्येक आयाम Build Variants की संख्या को गुणा करता है। एक आयाम में 4 flavors + 2 build types = 8 वेरिएंट। दो आयामों में 4 + 4 = 16 वेरिएंट। 3 से अधिक आयाम और कुल 10-12 वेरिएंट का उपयोग न करने की अनुशंसा की जाती है।

क्या flavor के लिए मेनिफ़ेस्ट को ओवरराइड किया जा सकता है?

हाँ, source set src/<flavor>/AndroidManifest.xml के माध्यम से। मेनिफ़ेस्ट मुख्य के साथ मर्ज होता है। पूरे ब्लॉक को बदलने के लिए, tools:node="replace" का उपयोग करें। उदाहरण के लिए, किसी विशिष्ट flavor के लिए ऐप लेबल या अनुमतियाँ बदलें।

flavor-विशिष्ट निर्भरताएँ कैसे जोड़ें?

<flavorName>Implementation कॉन्फ़िगरेशन का उपयोग करें। उदाहरण: freeImplementation 'com.google.android.gms:play-services-ads:23.0.0'। यह निर्भरता केवल मुफ्त वेरिएंट बनाते समय शामिल की जाएगी। भुगतान वाले के लिए: paidImplementation। सामान्य निर्भरताएँ implementation के माध्यम से निर्दिष्ट की जाती हैं।

Product Flavor, Build Type से कैसे अलग है?

Product Flavor उत्पाद संस्करण (free, paid, demo) परिभाषित करता है, Build Type बिल्ड विधि (debug, release) परिभाषित करता है। Flavors applicationId, versionName, संसाधनों को ओवरराइड कर सकते हैं। Build Type debuggable, minification, signing को नियंत्रित करता है। दोनों ऑर्थोगोनल हैं और Build Variant में संयुक्त होते हैं।

क्या Jetpack Compose के साथ Product Flavor का उपयोग किया जा सकता है?

हाँ, Product Flavors बिना किसी प्रतिबंध के Compose के साथ काम करते हैं। विभिन्न flavors में source sets या सार वर्ग कार्यान्वयन के माध्यम से अलग-अलग Compose स्क्रीन हो सकती हैं। आप flavor-विशिष्ट Compose निर्भरताएँ भी जोड़ सकते हैं: freeImplementation 'androidx.compose.ui:ui-tooling'

सारांश

  • Product Flavor — एक कोड बेस से ऐप के कई संस्करण बनाने के लिए Gradle तंत्र।
  • Flavor Dimensions flavors को आयामों में समूहित करते हैं, जिससे ऐप के विभिन्न पहलुओं को संयोजित किया जा सकता है।
  • Source sets एक flavor के लिए मुख्य निर्देशिका को संशोधित किए बिना संसाधनों, कोड और मेनिफ़ेस्ट को ओवरराइड करते हैं।
  • इंटरफ़ेस + flavor कार्यान्वयन कार्यक्षमता को अलग करने के लिए एक स्वच्छ आर्किटेक्चरल दृष्टिकोण है।
  • Flavor-विशिष्ट निर्भरताएँ अनावश्यक लाइब्रेरी को अनुपयुक्त संस्करणों में जाने से रोकती हैं।
  • बहु-मॉड्यूल परियोजनाएँ Convention Plugins या एकाधिक वेरिएंट प्रकाशन के माध्यम से flavor सिंक्रनाइज़ेशन की आवश्यकता होती है।
  • अनुशंसा: प्रोजेक्ट में 3 से अधिक flavor आयाम और कुल 10 से अधिक Build Variants न हों।

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें