A Build Variant az Android-fejlesztésben a build type és product flavor kombinációja, amely meghatározza, hogyan épül fel az APK vagy AAB: milyen paraméterekkel, erőforrásokkal és kóddal. Minden fordítási változat külön Gradle-konfiguráció saját applicationId-val, aláírási kulcsokkal és függőségekkel. A Google Android Developers, 2025 szerint a Build Variants helyes beállítása 40%-kal csökkenti a fordítási időt a szükségtelen erőforrások kizárásával minden változathoz. A fordítási változatok rendszere a konfigurációkezelés alapja a modern Android-projektekben.
Főbb pontok
Build Variant — egy Build Type és egy Product Flavor kombinációjának eredménye. Ha a projektben nincs Product Flavor definiálva, akkor a Build Variant egybeesik a Build Type-tal. A Gradle automatikusan generálja a változatok teljes készletét az összes FlavorDimensions, Product Flavors és Build Types Descartes-szorzataként. Például a free/paid flavor és a debug/release típusok esetén 8 változat jön létre: freeDebug, freeRelease, paidDebug, paidRelease.
Minden Build Variant saját nevet kap <Flavor><Type> formátumban, a flavor nagybetűvel. Ehhez a változathoz a Gradle külön feladatokat generál: assembleFreeDebug, installFreeDebug, bundleFreeRelease. Az Android Studio-ban a változatok közötti váltás a Build Variants panelen (View → Tool Windows → Build Variants) keresztül érhető el. A változat kiválasztása befolyásolja, hogy melyik kód fordul le, mely erőforrások kerülnek bele, és melyik APK/AAB jön létre.
A Build Variants rendszer három kulcsfeladatot old meg: konfigurációk szétválasztása különböző környezetekhez (dev/staging/production), az alkalmazás több verziójának létrehozása (free/paid) és a build-ek A/B tesztelése. Build Variants nélkül a fejlesztőknek manuálisan kellene váltaniuk a jelölőket és konfigurációkat, ami emberi hibákhoz vezet. A Gradle Inc., 2024 kutatása szerint a Build Variants bevezetése 60%-kal csökkenti a fordítási hibák számát három vagy több telepítési környezettel rendelkező projektekben.
AGP (Android Gradle Plugin) a konfigurációs fázisban kiszámítja az összes kombinációt. Ha a projektnek két dimenziója van, két, illetve három flavor-rel, a Gradle 2 × 2 × 3 = 12 kombinációt hoz létre, megszorozva a Build Types számával (általában 2). Minden kombináció egyedi nevet és feladatkészletet kap. Az AGP automatikusan hozzáad egy source set-et minden változathoz: src/freeDebug/, src/paidRelease/, valamint az általánosított src/free/ és src/debug/. Az erőforrások olvasásának prioritása: variant → flavor → type → main.
// Példa: 4 Build Variants
// flavorDimensions "version", "server"
// version: demo, prod
// server: mock, live
// buildTypes: debug, release
// Összesen: 2 × 2 × 2 = 8 változat
android {
flavorDimensions "version", "server"
productFlavors {
demo { dimension "version" }
prod { dimension "version" }
mock { dimension "server" }
live { dimension "server" }
}
}
Build Type meghatározza, hogyan fordítódik az alkalmazás — hibakeresési információkkal vagy anélkül, optimalizálással vagy anélkül, milyen aláírással. Product Flavor meghatározza, hogy mi fordítódik — a termék melyik verziója. Build Type — a fordítás mechanizmusa (debug, release, staging). Product Flavor — a termék változata (free, paid, enterprise, demo). Mindkét fogalom ortogonális: bármely Build Type alkalmazható bármely Product Flavor-ra.
A Build Type alapértelmezetten tartalmazza a debug (debuggable=true, minification=false, signing=debug.keystore) és release (debuggable=false, minification=true, signing=production.keystore) típusokat. A Product Flavor alapértelmezetten egyetlenegy, név nélküli (valójában a main source set). A fejlesztő saját Build Types-okat (pl. „staging“ debuggable=true és minification=true értékekkel) és Product Flavors-okat adhat hozzá tetszőleges számban. A különbség abban is rejlik, hogy a Build Type nem csoportosítható dimenziókba, míg a Product Flavor igen.
A legfontosabb gyakorlati különbség: a build.gradle-ben lévő defaultConfig minden Variants-ra vonatkozik, de felülírható a productFlavors és buildTypes blokkokban. A buildType-ban hozzáadott BuildConfigField az adott típus összes flavor-jában látható, a productFlavor-ban hozzáadott pedig az adott flavor összes típusában. Ha a mező mindkét helyen definiálva van — a buildType prioritást élvez (utolsóként kerül alkalmazásra a láncban).
| Jellemző | Build Type | Product Flavor |
|---|---|---|
| Cél | Hogyan fordítsunk | Mit fordítsunk |
| Példák | debug, release, staging | free, paid, demo, enterprise |
| Alapértelmezett | debug + release | egy (main) |
| Source Set | src/debug/, src/release/ | src/free/, src/paid/ |
| Dimenziók | nem | flavorDimensions |
| Alkalmazás | flavor után, felülír | defaultConfig után |
| BuildConfigField | felülírja a flavor-t | felülírja a defaultConfig-ot |
A Build Variants beállítása a modul szintű build.gradle fájl android blokkjában történik. Először a buildTypes deklarálódik a paramétereivel, majd a flavorDimensions és productFlavors. A Gradle automatikusan létrehozza a változatokat ezen deklarációk alapján. Minden változat örökli a modul defaultConfig-ját, felülírva a megadott mezőket. A deklarálás sorrendje befolyásolja a prioritást: a buildTypes a productFlavors után kerül alkalmazásra.
Egy adott Build Variant eléréséhez a Gradle szkriptekben a android.applicationVariants (az app modulhoz) vagy android.libraryVariants (a könyvtári modulhoz) használható. Ez egy kollekció, amelyen iterálható, és az egyes változatok konfigurációja módosítható a konfigurációs időben. Például programozottan hozzáadható buildConfigField az összes olyan változathoz, amely tartalmazza a „demo” szót.
Az Android Gradle Plugin 8.x támogatást adott a onVariants-hoz — egy tisztább API a változatok lambdákon keresztüli konfigurálásához. A régi API (variantOutput, variantFilter) elavultnak van jelölve. Javasolt az onVariants használata az onEach mellett a könyvtári modulokhoz. A variantOutput-ról onVariants-ra való migráció — javasolt lépés az AGP 7.x-ről 8.x-re történő frissítésekor.
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)
}
}
Minden Build Variant saját source sets hierarchiát kap — forráskódot, erőforrásokat és manifestet tartalmazó könyvtárakat. A source set a src/<variantName>/ könyvtárban található (pl. src/freeDebug/) és tartalmazhat java/, res/, AndroidManifest.xml, assets/ mappákat. Ha egy fájl létezik a változat source set-jében, felülírja az azonos nevű fájlt a fő source set-ből (src/main/). Az erőforrások esetében egyesítés működik, nem helyettesítés — a rendszer az összes aktív source sets erőforrásait kombinálja, előnyben részesítve a változatspecifikusakat.
A Build Variant source sets láncban épülnek fel: src/main/ → src/flavor/ → src/type/ → src/flavorType/. Például a paidRelease esetén először a main, majd a paid, majd a release, végül a paidRelease kerül alkalmazásra. Minden következő source set felülírja az előzőt. Ez azt jelenti, hogy a src/release/res/values/strings.xml felülírja ugyanazokat a karakterláncokat a src/paid/-ból, de a src/paid/release/res/ még prioritásosabb.
A source sets használata a változatokhoz — az erőforrások testreszabásának ajánlott módja. Ahelyett, hogy a BuildConfig.FLAVOR-t ellenőriznénk a kódban és elágaztatnánk a logikát, egyszerűen elhelyezhetők különböző fájlok különböző source sets-ekbe. Például a free és paid verziók ikonjai a src/free/res/ és src/paid/res/ mappákba kerülnek, a különböző engedélyekkel rendelkező AndroidManifest pedig a src/free/AndroidManifest.xml és src/paid/AndroidManifest.xml fájlokba. Ez tisztább, gyorsabb (az erőforrások fordítódnak, nem futásidőben ellenőrződnek) és biztonságosabb (nem lehet véletlenül bekapcsolni a fizetős funkciókat az ingyenes verzióban egy kódhiba miatt).
A többmodulos projektekben minden modul (könyvtár) saját Build Variants-okkal rendelkezhet. Az AGP automatikusan szinkronizálja a változatokat: ha az app modul paidRelease-t fordít, az összes függő könyvtár is a paidRelease-nek megfelelő változataiban fordul. A probléma akkor merül fel, ha a könyvtárnak nincsenek product flavors-ai, de az app modulnak igen — ekkor a könyvtár egyszer fordul (release vagy debug típustól függően).
A könyvtári modulok esetében a Build Variant alapértelmezetten egybeesik az app modul Build Type-jával, mivel a könyvtáraknak nincsenek product flavors-aik. Ha a könyvtárnak alkalmazkodnia kell az app modul flavor-jához, akkor ugyanazokat a flavorDimensions és productFlavors értékeket kell deklarálni a könyvtárban. Az AGP név szerinti teljes egyezés alapján párosítja a flavor-t. A Gradle javasolja a flavor-ok szinkronizálását a build konfiguráción keresztül a gyökérprojektben a subprojects vagy Convention Plugins segítségével.
Az AGP 8.1-től kezdve a könyvtárak közzétehetnek multiple variants-okat — a könyvtár összes változatát egyszerre közzétehetik egy maven tárolóban. Ez megoldja a problémát, amikor az app modul paid flavor-t használ, de a könyvtár csak free verzióban van közzétéve. A multiple variants publishing (MVP) lehetővé teszi a függő projekt számára, hogy automatikusan kiválassza a szükséges változatot. Az MVP bekapcsolásához hozzá kell adni a publishing { multipleVariants { ... } } blokkot a könyvtár build.gradle fájljához.
Néha szükséges a Build Variants egy részének kikapcsolása — például ha a mockRelease kombinációnak nincs értelme (a mock szerver nem kerülhet éles környezetbe). A Gradle variantFilter-t biztosít — egy DSL blokkot, amelyben ellenőrizhetők az egyes változatok tulajdonságai, és kikapcsolhatók a setIgnore(true) segítségével. A VariantFilter a konfigurációs fázisban kerül alkalmazásra, a feladatok létrehozása előtt, így a kikapcsolt változat nem generál assemble és install feladatokat.
A szűrés a fordítás gyorsításához is hasznos. Ha a projektben 8 változat van, és a fejlesztő csak egyen dolgozik, a maradék 7 változat akkor is átmegy a konfiguráción (configuration phase). A variantFilter használatakor a kikapcsolt változatok nem hoznak létre feladatokat, ami 30-50%-kal csökkenti a konfigurációs időt a 6+ flavor dimenzióval rendelkező projektekben. CI/CD-ben a változatok dinamikusan szűrhetők parancssori paraméterekkel: -PbuildOnly=paidRelease.
android {
variantFilter { variant ->
// Kikapcsoljuk a mock-ot release-hez és a demo-t production-höz
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)
}
}
}
// Dinamikus szűrés paramétereken keresztül
if (project.hasProperty("buildOnly")) {
def target = project.property("buildOnly")
android.variantFilter { variant ->
variant.setIgnore(variant.name != target)
}
}
Gyakran ismételt kérdések
Nincs korlátozás, de a Gradle az összes flavor és típus Descartes-szorzatát hozza létre. Ha 3 dimenziója van 3 flavor-rel és 3 build type-pal — 27 változatot kap. Túl sok változat lelassítja a konfigurációt. Javasolt legfeljebb 10-12 változat egy modulban.
A flavorDimensions a Product Flavors-okat független tengelyekbe csoportosítja. Például „tier“ (free, paid) és „region“ (us, eu) dimenzió. Dimenziók nélkül az összes flavor egy tengelyhez tartozik, és a Gradle csak egy flavor-t választ ki az összes közül (nem lehet free+us és paid+eu külön változatként).
A productFlavor vagy buildType blokkban adja meg az applicationId-t. Például a free verzióhoz: free { applicationId "com.example.app.free" }. A manifestben használja a ${applicationId} kifejezést — a Gradle automatikusan behelyettesíti az értéket. Ez lehetővé teszi mindkét változat telepítését egy eszközre.
Az iOS-ben a Build Variants megfelelője a Scheme + Configuration kombináció. Az Xcode Schemes a Debug/Release konfigurációkon keresztül állíthatók be különböző paraméterekkel. Több verzióhoz (free/paid) a Build Configurations és Preprocessor Macros használatos. Androidban a koncepció formálisabb és beépült a Gradle-be.
Igen, minden változat eltérő APK-mérettel rendelkezhet. A debug build-ek tartalmaznak hibakeresési információkat, SDK-t és nem támogatott erőforrásokat. A release build-ek minifikációval és erőforrás-csökkentéssel minimális méretet adnak. A Product Flavor is befolyásolja: a free verzió fizetős könyvtárak nélkül kisebb lesz, mint a paid verzió ezen könyvtárak méretével.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is