Build Variant — шта је, build type и product flavor у Android-у

Аутор: IT Sectr Објављено: 2026-05-30 Време читања: 9 мин

Build Variant у Android развоју је комбинација build type-а и product flavor-а која одређује како ће бити састављен APK или AAB: са којим параметрима, ресурсима и кодом. Свака варијанта компилације представља засебну Gradle конфигурацију са сопственим applicationId, кључевима за потписивање и укљученим зависностима. Према Google Android Developers, 2025, правилно подешавање Build Variants смањује време компилације до 40% захваљујући искључивању непотребних ресурса за сваку варијанту. Систем варијанти компилације представља основу управљања конфигурацијом у савременим Android пројектима.

Главне тачке

  • Build Variant — комбинација једног Build Type-а и једног Product Flavor-а.
  • Build Type задаје режим компилације: debug (отклањање грешака) или release (објављивање).
  • Product Flavor дефинише верзију апликације: free, paid, demo, enterprise.
  • Gradle аутоматски генерише задатке за сваки Build Variant, укључујући install и assemble.
  • Ресурси и код могу бити преиначени за сваку варијанту кроз одговарајуће source sets.

Шта је Build Variant?

Build Variant — је резултат комбинације једног Build Type-а и једног Product Flavor-а. Ако у пројекту нису дефинисани Product Flavor, Build Variant се поклапа са Build Type-ом. Gradle аутоматски генерише пун скуп варијанти као Декартов производ свих FlavorDimensions, Product Flavors и Build Types. На пример, за flavor free/paid и типове debug/release биће креирано 8 варијанти: 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% у пројектима са три или више окружења за примену.

Како Gradle генерише варијанте

AGP (Android Gradle Plugin) израчунава све комбинације у фази конфигурације. Ако пројекат има две димензије са два и три flavor, Gradle ће креирати 2 × 2 × 3 = 12 комбинација, помножених са бројем Build Types (обично 2). Свака комбинација добија јединствено име и скуп задатака. AGP аутоматски додаје source set за сваку варијанту: src/freeDebug/, src/paidRelease/, као и уопштене src/free/ и src/debug/. Приоритет читања ресурса: variant → flavor → type → main.

groovy
// Пример: 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 одређује како се апликација компајлира — са информацијама за отклањање грешака или без, са оптимизацијом или без, са којим потписивањем. Product Flavor одређује шта се компајлира — коју верзију производа. Build Type — је механизам компилације (debug, release, staging). Product Flavor — је варијанта производа (free, paid, enterprise, demo). Оба концепта су ортогонална: било који Build Type се може применити на било који Product Flavor.

Build Type подразумевано укључује 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 Type не може груписати у димензије, а Product Flavor — може.

Кључна практична разлика: defaultConfig у build.gradle примењује се на све Variants, али може бити преиначен у productFlavors и buildTypes. BuildConfigField додат у buildType видљив је у свим flavor-има овог типа, а додат у productFlavor — у свим типовима овог flavor-а. Ако је поље дефинисано и тамо и тамо — приоритет има buildType (примењује се последњи у ланцу).

Упоредна табела

КарактеристикаBuild TypeProduct Flavor
НаменаКако компајлиратиШта компајлирати
Примериdebug, release, stagingfree, paid, demo, enterprise
Подразумеваноdebug + releaseједан (main)
Source Setsrc/debug/, src/release/src/free/, src/paid/
ДимензијенеflavorDimensions
Применапосле flavor, преиначавапосле defaultConfig
BuildConfigFieldпреиначава flavorпреиначава defaultConfig

Подешавање Build Variants у build.gradle

Приоритет конфигурација

Подешавање Build Variants се врши у блоку android датотеке build.gradle на нивоу модула. Прво се декларишу buildTypes са својим параметрима, затим flavorDimensions и productFlavors. Gradle аутоматски креира варијанте на основу ових декларација. Свака варијанта наслеђује defaultConfig модула, преиначујући одређена поља. Редослед декларације утиче на приоритет: buildTypes се примењују после productFlavors.

За приступ одређеном Build Variant-у у Gradle скриптама користи се android.applicationVariants (за app модул) или android.libraryVariants (за библиотечки модул). Ово је колекција по којој се може итерирати и мењати конфигурација сваке варијанте у време конфигурације. На пример, може се програмски додати buildConfigField за све варијанте које садрже реч „demo“.

Android Gradle Plugin 8.x додао је подршку за onVariants — чистији API за подешавање варијанти преко ламбди. Стари API (variantOutput, variantFilter) је означен као застарео. Препоручује се коришћење onVariants заједно са onEach за библиотечке модуле. Миграција са variantOutput на onVariants — препоручени корак при ажурирању AGP са 7.x на 8.x.

groovy
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)
    }
}

Source Sets и преиначавање ресурса

Сваки Build Variant добија сопствену хијерархију source sets — директоријума са изворним кодом, ресурсима и манифестом. Source set се налази у src/<variantName>/ (на пример, src/freeDebug/) и може садржати java/, res/, AndroidManifest.xml, assets/. Ако датотека постоји у source set-у варијанте, она преиначава датотеку са истим именом из главног source set-а (src/main/). За ресурсе ради спајање, а не замена — систем комбинује ресурсе из свих активних source sets, дајући приоритет специфичнима за варијанту.

Source sets за Build Variant се граде у ланцу: src/main/src/flavor/src/type/src/flavorType/. На пример, за paidRelease прво се примењује main, затим paid, затим release, затим paidRelease. Сваки следећи source set преиначава претходни. То значи да src/release/res/values/strings.xml преиначава исте низове из src/paid/, али src/paid/release/res/ је још приоритетнији.

Коришћење source sets за варијанте — препоручени начин прилагођавања ресурса. Уместо проверавања BuildConfig.FLAVOR у коду и гранања логике, могуће је једноставно сместити различите датотеке у различите source sets. На пример, иконе за free и paid верзије стављају се у src/free/res/ и src/paid/res/, а AndroidManifest са различитим дозволама — у src/free/AndroidManifest.xml и src/paid/AndroidManifest.xml. Ово је чистије, брже (ресурси се компајлирају, а не проверавају у runtime-у) и сигурније (не може се случајно укључити плаћена функционалност у бесплатној верзији због грешке у коду).

Build Variant у вишемодулним пројектима

У вишемодулним пројектима сваки модул (библиотека) може имати сопствене Build Variants. AGP аутоматски синхронизује варијанте: ако app модул компајлира paidRelease, све зависне библиотеке се такође компајлирају у својим варијантама које одговарају paidRelease. Проблем настаје када библиотека нема product flavors, а app модул има — тада се библиотека компајлира једном (release или debug у зависности од типа).

За библиотечке модуле, Build Variant подразумевано се поклапа са Build Type app модула, јер библиотеке немају product flavors. Ако библиотека треба да се прилагоди flavor-у app модула, потребно је декларисати исте flavorDimensions и productFlavors у библиотеци. AGP упарује flavor по пуном поклапању имена. Gradle препоручује синхронизацију flavor-а кроз конфигурацију градње у кореном пројекту помоћу subprojects или Convention Plugins.

Почевши од AGP 8.1, библиотеке могу објавити multiple variants — објавити у maven репозиторијум све варијанте библиотеке истовремено. Ово решава проблем када app модул користи paid flavor, а библиотека је објављена само за free. Multiple variants publishing (MVP) омогућава зависном пројекту да аутоматски изабере потребну варијанту. За укључивање MVP, потребно је додати publishing { multipleVariants { ... } } у build.gradle библиотеке.

Филтрирање и искључивање варијанти

Динамичко филтрирање кроз CI/CD

Понекад је потребно искључити део Build Variants — на пример, ако комбинација mockRelease нема смисла (mock сервер не треба да доспе у продукцију). Gradle пружа variantFilter — DSL блок у којем се могу проверити својства сваке варијанте и искључити је кроз setIgnore(true). VariantFilter се примењује у фази конфигурације, пре креирања задатака, тако да искључена варијанта не генерише assemble и install задатке.

Филтрирање је такође корисно за убрзавање компилације. Ако пројекат има 8 варијанти, а програмер ради само на једној, преосталих 7 варијанти ипак пролазе конфигурацију (configuration phase). Коришћењем variantFilter, искључене варијанте не креирају задатке, што смањује време конфигурације за 30-50% за пројекте са 6+ flavor димензија. У CI/CD се могу динамички филтрирати варијанте кроз параметре командне линије -PbuildOnly=paidRelease.

groovy
android {
    variantFilter { variant ->
        // Искључујемо mock за release и demo за production
        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)
    }
}

Често постављана питања

Колико Build Variants се може креирати?

Нема ограничења, али Gradle креира Декартов производ свих flavor-а и типова. Ако имате 3 димензије по 3 flavor и 3 build type — добићете 27 варијанти. Превише варијанти успорава конфигурацију. Препоручује се не више од 10-12 варијанти у једном модулу.

Чему служе flavorDimensions?

flavorDimensions групишу Product Flavors у независне осе. На пример, димензија „tier“ (free, paid) и „region“ (us, eu). Без димензија, сви flavor припадају једној оси и Gradle ће бирати само један flavor од свих (не могу се имати free+us и paid+eu као засебне варијанте).

Како преиначити applicationId за варијанту?

У блоку productFlavor или buildType наведите applicationId. На пример, за free верзију: free { applicationId "com.example.app.free" }. У манифесту користите ${applicationId} — Gradle ће аутоматски заменити вредност. Ово омогућава инсталацију обе варијанте на истом уређају.

Могу ли се користити Build Variants у iOS?

У iOS, аналогон Build Variants је комбинација Scheme + Configuration. Xcode Schemes се подешавају кроз конфигурације Debug/Release са различитим параметрима. За више верзија (free/paid) користе се Build Configurations и Preprocessor Macros. На Android-у, концепт је формализованији и уграђен у Gradle.

Да ли Build Variant утиче на величину APK-а?

Да, свака варијанта може имати различиту величину APK-а. debug компилације укључују информације за отклањање грешака, SDK и неподржане ресурсе. Release компилације са минификацијом и смањењем ресурса дају минималну величину. Product Flavor такође утиче: free верзија без плаћених библиотека биће мања од paid верзије за величину тих библиотека.

Закључак

  • Build Variant — комбинација једног Build Type-а и једног Product Flavor-а која одређује конфигурацију компилације.
  • Build Type управља режимом компилације (debug/release/staging), а Product Flavor — верзијом производа (free/paid).
  • Source sets омогућавају преиначавање кода, ресурса и манифеста за сваку варијанту компилације.
  • VariantFilter искључује непотребне комбинације, убрзавајући Gradle конфигурацију за 30-50%.
  • Вишемодулни пројекти захтевају синхронизацију flavor-а кроз све модуле или multiple variants publishing.
  • BuildConfigField и source sets — два чиста начина прилагођавања понашања између варијанти.
  • Препорука: не креирајте више од 10-12 варијанти у једном пројекту, групишите димензије смислено.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође