Android dasturlashda Product Flavor — umumiy kod bazasidan bitta ilovaning bir necha variantlarini yaratishga imkon beruvchi Gradle mexanizmidir. Har bir flavor o‘z applicationId, resurs, bog‘liqlik va funksionallikka ega bo‘lishi mumkin — masalan, bepul va pulli versiyalar. Google Android Developers, 2025 ma’lumotiga ko‘ra, Product Flavors Build Variants tizimiga kiradi va flavorDimensions orqali Build Types bilan birlashadi. Bu Google Play-da ilovaning bir necha versiyasini nashr qilish uchun standart yondashuvdir.
Asosiy
Product Flavor — android.productFlavors blokidagi mahsulot variantini tavsiflovchi Gradle konfiguratsiyasi. Har bir flavor applicationId, versionName, versionCode, minSdkVersion, targetSdkVersion, signingConfig va boshqa defaultConfig parametrlarini qayta belgilashi mumkin. Product Flavors son chekloviga ega emas: loyihada 2, 5, 10 flavor bo‘lishi mumkin — Gradle barcha kombinatsiyalarni qayta ishlaydi.
Product Flavor codebase reuse muammosini hal qiladi — bitta repozitariydan bir necha turli ilovalarni qurish kerak bo‘lganda. Odatdagi stsenariylar: reklamali bepul versiya va reklamasiz pulli; cheklangan funksiyali demo versiya; korporativ va iste’molchi versiyalari; turli mijozlar uchun white-label ilovalar. Product Flavors bo‘lmaganida, har bir versiyani alohida loyihada saqlash kerak bo‘lardi, bu kodning 60-70% takrorlanishiga olib keladi.
Tarixiy jihatdan, Product Flavors Android Gradle Plugin 0.9 (2013) da ant konfiguratsiyalarning o‘rnini bosuvchi sifatida paydo bo‘ldi. Bungacha dasturchilar turli versiyalar uchun alohida loyihalardan yoki qurishdan oldin resurslarni qo‘lda almashtirishdan foydalanardilar. AGP da flavor-larning joriy etilishi yondashuvni birlashtirdi va uni standartga aylantirdi. JetBrains, 2024 so‘roviga ko‘ra, bir necha versiyali Android loyihalarining 78% i Product Flavors dan foydalanadi, qolganlari — BuildConfig yoki reflection orqali qo‘lda o‘tish.
Build Type qurish jarayonini boshqaradi (debug tuzatish bilan, release optimallashtirish bilan). Product Flavor qurish mazmunini boshqaradi (pulli funksiyalarsiz free, ular bilan paid). Build Type infratuzilma sozlamasi, Product Flavor — mahsulot sozlamasi. Ikkala tushuncha ortogonaldir: free-flavor ning debug versiyasi free-flavor ning release versiyasidan faqat kompilyatsiya parametrlari bilan farqlanadi, funksionallik bilan emas. Product Flavor tuzatuvchini o‘chirish uchun ishlatilmaydi — bu Build Type vazifasi.
Flavor Dimensions (o‘lchamlar) — Product Flavors ni mustaqil kategoriyalarga guruhlash mexanizmi. Agar ilova bepul/pulli versiyaga va alohida Amerika/Yevropa mintaqasiga ega bo‘lsa, flavour ikki o‘lchamga guruhlanadi: „tier” (free, paid) va „region” (us, eu). Gradle o‘lchamlarning dekart ko‘paytmasini yaratadi: freeUs, freeEu, paidUs, paidEu — 4 variant. O‘lchamlarsiz, Gradle barcha to‘rt flavour-ni bir tekislik sifatida qabul qiladi va faqat bittasi tanlanishi mumkin edi.
O‘lchamlar flavorDimensions blokida satr yoki satrlar ro‘yxati sifatida e’lon qilinadi. O‘lchamlar tartibi source sets prioritetiga ta’sir qiladi: birinchi o‘lcham eng yuqori prioritetga ega. Agar o‘lcham A (tier) birinchi bo‘lsa, resurs ziddiyati holatida src/free/ src/us/ ni qayta belgilaydi. Tartib shuningdek Variant nomlanishiga ta’sir qiladi: avval birinchi o‘lchamning flavour-i, keyin ikkinchisining, so‘ng Build Type: freeUsDebug.
O‘lchamlar soni cheklanmagan, lekin har bir yangi o‘lcham Build Variants sonini ko‘paytiradi. 4 o‘lchamli (har birida 2 flavour) va 2 build types loyiha uchun: 2 × 2 × 2 × 2 × 2 = 32 variant. Amaliy chegara — 3 o‘lcham (maksimal 8-12 variant). Ko‘proq — Gradle konfiguratsiyasi sekinlashadi va Android Studio da Build Variants paneli o‘qib bo‘lmas holga keladi.
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
}
}
}
// Natija: freeMinApi21, freeMinApi26, paidMinApi21, paidMinApi26
// Har biri × debug/release = 8 Build Variants
Product Flavor yaratish uchun android ichida productFlavors bloki qo‘shilishi, flavor nomi va parametrlari ko‘rsatilishi kerak. Flavor ning minimal e’loni nom va dimension. Qolgan barcha parametrlar defaultConfig dan meros qilib olinadi va qayta belgilanishi mumkin. Flavor defaultConfig ni to‘liq meros qiladi, jumladan applicationId, versionCode va testInstrumentationRunner.
Har bir flavor applicationId ni qayta belgilashi mumkin — bu bitta qurilmada bir vaqtning o‘zida bir necha ilova versiyasini o‘rnatishga imkon beradi. Masalan, free versiyasi com.example.app.free, paid esa com.example.app.paid bo‘ladi. Agar applicationId qayta belgilanmasa, barcha flavour bir xil identifikatorga ega bo‘ladi va ularni parallel o‘rnatish mumkin bo‘lmaydi. applicationId manifestdagi package bilan mos kelishi kerak (agar applicationIdSuffix ishlatilmasa).
AGP 8+ build.gradle uchun Groovy o‘rniga Kotlin DSL dan foydalanishni tavsiya qiladi. Kotlin DSL konfiguratsiyaga tip-xavfsiz kirishni ta’minlaydi: IDE parametr nomlarini taklif qiladi, kompilyatsiya bosqichida tiplarni tekshiradi va xatolarni ajratib ko‘rsatadi. Groovy dan Kotlin DSL ga migratsiya odatda qo‘shtirnoqlarni qavslar bilan almashtirish va tiplarni qo‘shishdan iborat. AGP orqaga mos keladi — ikkala sintaksis bir loyihada parallel ishlaydi.
// 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")
}
}
}
Har bir Product Flavor o‘z source set ini yaratadi — src/<flavorName>/ katalogi. Bu katalogda qayta belgilangan resurslar, manbalar va manifest joylashtirilishi mumkin. Flavor source set main ustida qatlam sifatida ishlaydi: src/free/res/ dagi fayllar bir xil nomdagi src/main/res/ fayllarini qayta belgilaydi. Bu asosiy kodni o‘zgartirmasdan har bir flavor uchun turli satrlar, ikonkalar, ranglar va maketlarga ega bo‘lishga imkon beradi.
Java/Kotlin sinflarini qayta belgilash uchun ikkita yondashuv mavjud: flavor-specific implementation (har bir flavor da abstrakt sinfning implementatsiyasi) va BuildConfig field (kodda shoxlanish). Birinchi yondashuv tozaroq: main da interfeys yoki abstrakt sinf belgilaysiz, aniq implementatsiyalar esa src/free/ va src/paid/ da. Qurish paytida faqat joriy flavor ning implementatsiyasi kompilyatsiya qilinadi. Bu bir vaqtning o‘zida afzalliklarni beradi: kichikroq APK hajmi (pulli kod free versiyasiga kirmaydi) va xavfsizlik (pulli funksiyani tasodifan chaqirish mumkin emas).
Source set flavor dagi AndroidManifest.xml o‘rnini bosmaydi, aksincha main manifest bilan birlashadi. Birlashish Android qoidalariga ko‘ra amalga oshiriladi: bir elementdagi bir xil atributlar qayta belgilanadi, noyoblari qo‘shiladi. Masalan, agar main manifestda INTERNET ruxsati e’lon qilingan bo‘lsa, free da esa yo‘q, internet qoladi. Lekin tools:node="replace" ma’lum bir flavor uchun butun manifest blokini almashtirishga imkon beradi. Bu turli flavour turli ruxsatlarni talab qilganda foydalidir (paid uchun SD ga yozish, free uchun kamera).
<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>
Odatdagi stsenariyni ko‘rib chiqamiz: free — reklamali va asosiy funksiyali versiya, paid — reklamasiz, kengaytirilgan funksionallik bilan. Free versiyasi uchun applicationId „com.example.app.free”, paid uchun — „com.example.app.paid” o‘rnatiladi. Ikkala versiya bir qurilmada bir vaqtning o‘zida o‘rnatilishi mumkin, chunki applicationId Android tizimidagi ilovaning noyob identifikatoridir.
Arxitektura jihatdan bo‘linish interface + flavor implementation ga asoslanadi. Asosiy source set da PaymentService interfeysi e’lon qilinadi. src/free/ da AdMob orqali to‘lovdan oldin reklama ko‘rsatadigan implementatsiya joylashgan. src/paid/ da — to‘g‘ridan-to‘g‘ri to‘lov shlyuziga o‘tadigan implementatsiya. PaymentService dan foydalanadigan kod qaysi implementatsiya yuklanganini bilmaydi — bu kompilyatsiya bosqichida hal qilinadi. Bunday yondashuv free versiyasiga obuna boshqaruv kodi tushmasligini kafolatlaydi, hatto dasturchi uni tasodifan chaqirsa ham.
Turli flavor-lar uchun APK hajmi bog‘liqliklarni qo‘shish/chiqarish sababli 5-15 MB farq qilishi mumkin. Kutubxonani ma’lum bir flavor dan chiqarish uchun build.gradle da flavor-specific dependencies ishlatiladi: freeImplementation 'com.google.android.gms:play-services-ads:23.0.0'. Bu bog‘liqlik faqat free varianti uchun qo‘shiladi va paid versiyasining hajmini oshirmaydi. Umumiy bog‘liqliklar uchun implementation ishlatiladi — ular barcha flavor-larga kiritiladi.
// 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)
}
}
Ko‘p modulli loyihalarda kutubxona modullari o‘z Product Flavors ga ega bo‘lmasligi mumkin, bu muammo yaratadi: kutubxona bir marta (release sifatida) quriladi, ammo flavor-li app moduli kutubxonaning mos variantini kutadi. AGP 8.1 dan boshlab kutubxonalar publishing.multipleVariants bloki orqali multiple variants nashr qilishi mumkin — bu kutubxonaning barcha flavor variantlarini bitta maven omboriga nashr qilishga imkon beradi va app moduli avtomatik ravishda keraklisini tanlaydi.
Alternativ yondashuv — kutubxonada app modulidagi kabi flavorDimensions va productFlavors ni e’lon qilish. AGP bir o‘lchamda nomning to‘liq mosligiga ko‘ra flavour-ni avtomatik moslashtiradi. Kutubxonadagi flavor nomi app dagi nom bilan mos kelsa, AGP izchil variantlarni yaratadi. Qulay saqlash uchun umumiy flavour ta’riflarini Convention Plugin — loyihaning barcha modullariga qo‘llaniladigan Gradle plagini — ichiga joylashtirish tavsiya etiladi.
Nashr qilish uchun mo‘ljallanmagan kutubxonalar (ichki modullar) uchun ildiz loyihaning build.gradle fayli orqali flavour-ni sinxronlashtirish kifoya. Gradle barcha pastki loyihalarga konfiguratsiyani qo‘llash imkonini beruvchi subprojects metodini ta’minlaydi. Ammo subprojects da juda katta konfiguratsiya konfiguratsiya bosqichini sekinlashtirishini yodda tuting. Convention Plugins dan foydalanish tavsiya etiladi — ular bir marta kompilyatsiya qilinadi va qayta ishlatiladi, bu konfiguratsiya vaqtini 15-30% ga qisqartiradi.
Tez-tez beriladigan savollar
Miqdor cheklovi yo‘q, lekin har bir o‘lcham Build Variants sonini ko‘paytiradi. Bir o‘lchamda 4 flavour + 2 build types = 8 variant. Ikki o‘lchamda 4 + 4 = 16 variant. Eng ko‘pi bilan 3 o‘lcham va 10-12 jami variant tavsiya etiladi.
Ha, src/<flavor>/AndroidManifest.xml source set orqali. Manifest asosiy bilan birlashadi. Butun blokni almashtirish uchun tools:node="replace" dan foydalaning. Masalan, ilova yorlig‘ini yoki ma’lum bir flavor uchun ruxsatlarni o‘zgartirish.
<flavorName>Implementation konfiguratsiyasidan foydalaning. Misol: freeImplementation 'com.google.android.gms:play-services-ads:23.0.0'. Bu bog‘liqlik faqat free variantini qurishda qo‘shiladi. Paid uchun: paidImplementation. Umumiy bog‘liqliklar implementation orqali ko‘rsatiladi.
Product Flavor mahsulot versiyasini (free, paid, demo) belgilaydi, Build Type — qurish usulini (debug, release). Flavour applicationId, versionName va resurslarni qayta belgilashi mumkin. Build Type debuggable, minification va signing ni boshqaradi. Ikkalasi ortogonal va Build Variant da birlashadi.
Ha, Product Flavors Compose bilan cheklovlarsiz ishlaydi. Turli flavor source sets yoki abstrakt sinflar implementatsiyasi orqali turli Compose ekranlariga ega bo‘lishi mumkin. Shuningdek flavor-specific Compose bog‘liqliklarini qo‘shish mumkin: freeImplementation 'androidx.compose.ui:ui-tooling'.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.
Shuningdek o'qing