Build Variant — vad det är, build type och product flavor i Android

Författare: IT Sectr Publicerad: 2026-05-30 Lästid: 9 min

Build Variant i Android-utveckling är en kombination av build type och product flavor som bestämmer hur APK eller AAB ska byggas: med vilka parametrar, resurser och kod. Varje kompileringsvariant är en separat Gradle-konfiguration med eget applicationId, signeringsnycklar och inkluderade beroenden. Enligt Google Android Developers, 2025 minskar korrekt konfiguration av Build Variants kompileringstiden med 40% genom att utesluta onödiga resurser för varje variant. Systemet med kompileringsvarianter är grunden för konfigurationshantering i moderna Android-projekt.

Huvudpunkter

  • Build Variant — kombination av en Build Type och en Product Flavor.
  • Build Type anger kompileringsläge: debug (felsökning) eller release (utgåva).
  • Product Flavor definierar appversionen: free, paid, demo, enterprise.
  • Gradle genererar automatiskt uppgifter för varje Build Variant, inklusive install och assemble.
  • Resurser och kod kan åsidosättas för varje variant via motsvarande source sets.

Vad är Build Variant?

Build Variant — är resultatet av kombinationen av en Build Type och en Product Flavor. Om ingen Product Flavor är definierad i projektet sammanfaller Build Variant med Build Type. Gradle genererar automatiskt den fullständiga uppsättningen varianter som den kartesiska produkten av alla FlavorDimensions, Product Flavors och Build Types. Till exempel, för flavor free/paid och typerna debug/release skapas 8 varianter: freeDebug, freeRelease, paidDebug, paidRelease.

Varje Build Variant får ett eget namn i formatet <Flavor><Type> med flavor med stor bokstav. För denna variant genererar Gradle separata uppgifter: assembleFreeDebug, installFreeDebug, bundleFreeRelease. I Android Studio är växling mellan varianter tillgänglig via panelen Build Variants (View → Tool Windows → Build Variants). Valet av variant påverkar vilken kod som kompileras, vilka resurser som inkluderas och vilken APK/AAB som skapas.

Systemet Build Variants löser tre viktiga uppgifter: separation av konfigurationer för olika miljöer (dev/staging/production), skapande av flera versioner av appen (free/paid) och A/B-testning av byggen. Utan Build Variants skulle utvecklare behöva manuellt växla flaggor och konfigurationer, vilket leder till mänskliga fel. Enligt forskning från Gradle Inc., 2024 minskar implementeringen av Build Variants antalet kompileringsfel med 60% i projekt med tre eller fler distributionsmiljöer.

Hur Gradle genererar varianter

AGP (Android Gradle Plugin) beräknar alla kombinationer i konfigurationsfasen. Om projektet har två dimensioner med två respektive tre flavor, skapar Gradle 2 × 2 × 3 = 12 kombinationer, multiplicerat med antalet Build Types (vanligtvis 2). Varje kombination får ett unikt namn och en uppsättning uppgifter. AGP lägger automatiskt till en source set för varje variant: src/freeDebug/, src/paidRelease/, samt generaliserade src/free/ och src/debug/. Prioriteten för resursläsning: variant → flavor → type → main.

groovy
// Exempel: 4 Build Variants
// flavorDimensions "version", "server"
// version: demo, prod
// server: mock, live
// buildTypes: debug, release
// Totalt: 2 × 2 × 2 = 8 varianter

android {
    flavorDimensions "version", "server"

    productFlavors {
        demo { dimension "version" }
        prod { dimension "version" }
        mock { dimension "server" }
        live { dimension "server" }
    }
}

Build Type och Product Flavor: skillnader

Build Type bestämmer hur appen kompileras — med felsökningsinformation eller utan, med optimering eller utan, med vilken signering. Product Flavor bestämmer vad som kompileras — vilken version av produkten. Build Type — är kompileringsmekanismen (debug, release, staging). Product Flavor — är produktvarianten (free, paid, enterprise, demo). Båda begreppen är ortogonala: vilken Build Type som helst kan tillämpas på vilken Product Flavor som helst.

Build Type inkluderar som standard debug (debuggable=true, minification=false, signing=debug.keystore) och release (debuggable=false, minification=true, signing=production.keystore). Product Flavor är som standard en, utan namn (egentligen main source set). Utvecklaren kan lägga till egna Build Types (t.ex. “staging” med debuggable=true och minification=true) och Product Flavors i valfritt antal. Skillnaden ligger också i att Build Type inte kan grupperas i dimensioner, medan Product Flavor kan.

Den viktigaste praktiska skillnaden: defaultConfig i build.gradle tillämpas på alla Variants, men kan åsidosättas i productFlavors och buildTypes. BuildConfigField som läggs till i buildType är synlig i alla flavor av denna typ, och den som läggs till i productFlavor — i alla typer av denna flavor. Om fältet definieras både där och där — har buildType prioritet (tillämpas sist i kedjan).

Jämförelsetabell

EgenskapBuild TypeProduct Flavor
SyfteHur man kompilerarVad man kompilerar
Exempeldebug, release, stagingfree, paid, demo, enterprise
Standarddebug + releaseen (main)
Source Setsrc/debug/, src/release/src/free/, src/paid/
DimensionernejflavorDimensions
Tillämpningefter flavor, åsidosätterefter defaultConfig
BuildConfigFieldåsidosätter flavoråsidosätter defaultConfig

Konfigurera Build Variants i build.gradle

Prioritet för konfigurationer

Konfigurationen av Build Variants utförs i android-blocket i build.gradle-filen på modulnivå. Först deklareras buildTypes med sina parametrar, sedan flavorDimensions och productFlavors. Gradle skapar automatiskt varianter baserat på dessa deklarationer. Varje variant ärver modulens defaultConfig och åsidosätter angivna fält. Deklarationsordningen påverkar prioriteten: buildTypes tillämpas efter productFlavors.

För åtkomst till en specifik Build Variant i Gradle-skript används android.applicationVariants (för app-modulen) eller android.libraryVariants (för biblioteksmodulen). Detta är en samling som kan itereras över och konfigurationen för varje variant kan ändras under konfigurationstiden. Till exempel kan buildConfigField programmatiskt läggas till för alla varianter som innehåller ordet “demo”.

Android Gradle Plugin 8.x lade till stöd för onVariants — ett renare API för att konfigurera varianter via lambdas. Det gamla API:et (variantOutput, variantFilter) är markerat som föråldrat. Det rekommenderas att använda onVariants tillsammans med onEach för biblioteksmoduler. Migrering från variantOutput till onVariants — rekommenderat steg vid uppdatering av AGP från 7.x till 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 och åsidosättande av resurser

Varje Build Variant får sin egen hierarki av source sets — kataloger med källkod, resurser och manifest. Source set finns i src/<variantName>/ (t.ex. src/freeDebug/) och kan innehålla java/, res/, AndroidManifest.xml, assets/. Om en fil finns i variantens source set åsidosätter den filen med samma namn från huvud-source set (src/main/). För resurser fungerar sammanslagning, inte ersättning — systemet kombinerar resurser från alla aktiva source sets och ger prioritet till variantspecifika.

Source sets för Build Variant byggs i en kedja: src/main/src/flavor/src/type/src/flavorType/. Till exempel, för paidRelease tillämpas först main, sedan paid, sedan release, sedan paidRelease. Varje efterföljande source set åsidosätter den föregående. Detta innebär att src/release/res/values/strings.xml åsidosätter samma strängar från src/paid/, men src/paid/release/res/ är ännu mer prioriterad.

Att använda source sets för varianter — det rekommenderade sättet att anpassa resurser. Istället för att kontrollera BuildConfig.FLAVOR i koden och förgrena logik, kan olika filer helt enkelt placeras i olika source sets. Till exempel placeras ikoner för free- och paid-versionerna i src/free/res/ respektive src/paid/res/, och AndroidManifest med olika behörigheter — i src/free/AndroidManifest.xml och src/paid/AndroidManifest.xml. Detta är renare, snabbare (resurser kompileras, kontrolleras inte vid körning) och säkrare (betald funktionalitet kan inte oavsiktligt aktiveras i gratisversionen på grund av ett fel i koden).

Build Variant i multimodulprojekt

I multimodulprojekt kan varje modul (bibliotek) ha egna Build Variants. AGP synkroniserar automatiskt varianter: om app-modulen kompilerar paidRelease, kompileras även alla beroende bibliotek i sina varianter som motsvarar paidRelease. Problemet uppstår när biblioteket inte har product flavors, men app-modulen har — då kompileras biblioteket en gång (release eller debug beroende på typ).

För biblioteksmoduler sammanfaller Build Variant som standard med Build Type för app-modulen, eftersom bibliotek inte har product flavors. Om biblioteket måste anpassas till app-modulens flavor, måste samma flavorDimensions och productFlavors deklareras i biblioteket. AGP matchar flavor genom fullständig namnmatchning. Gradle rekommenderar att synkronisera flavor via byggkonfigurationen i rotprojektet med subprojects eller Convention Plugins.

Från och med AGP 8.1 kan bibliotek publicera multiple variants — publicera alla varianter av biblioteket samtidigt i ett maven-förvar. Detta löser problemet när app-modulen använder paid flavor, men biblioteket endast är publicerat för free. Multiple variants publishing (MVP) gör det möjligt för det beroende projektet att automatiskt välja den nödvändiga varianten. För att aktivera MVP måste publishing { multipleVariants { ... } } läggas till i bibliotekets build.gradle.

Filtrering och inaktivering av varianter

Dynamisk filtrering via CI/CD

Ibland är det nödvändigt att inaktivera en del av Build Variants — till exempel om kombinationen mockRelease inte är meningsfull (mock-servern bör inte nå produktion). Gradle tillhandahåller variantFilter — ett DSL-block där egenskaperna för varje variant kan kontrolleras och inaktiveras via setIgnore(true). VariantFilter tillämpas i konfigurationsfasen, före skapandet av uppgifter, så en inaktiverad variant genererar inte assemble- och install-uppgifter.

Filtrering är också användbart för att påskynda kompilering. Om projektet har 8 varianter och utvecklaren bara arbetar med en, går de återstående 7 varianterna ändå igenom konfiguration (configuration phase). Vid användning av variantFilter skapar inaktiverade varianter inga uppgifter, vilket minskar konfigurationstiden med 30-50% för projekt med 6+ flavordimensioner. I CI/CD kan varianter dynamiskt filtreras via kommandoradsparametrar -PbuildOnly=paidRelease.

groovy
android {
    variantFilter { variant ->
        // Inaktivera mock för release och demo för produktion
        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)
        }
    }
}

// Dynamisk filtrering via parametrar
if (project.hasProperty("buildOnly")) {
    def target = project.property("buildOnly")
    android.variantFilter { variant ->
        variant.setIgnore(variant.name != target)
    }
}

Vanliga frågor

Hur många Build Variants kan skapas?

Det finns inga begränsningar, men Gradle skapar den kartesiska produkten av alla flavor och typer. Om du har 3 dimensioner med 3 flavor och 3 build type — får du 27 varianter. För många varianter saktar ner konfigurationen. Rekommenderas inte mer än 10-12 varianter i en modul.

Vad är flavorDimensions till för?

flavorDimensions grupperar Product Flavors i oberoende axlar. Till exempel, dimension “tier” (free, paid) och “region” (us, eu). Utan dimensioner tillhör alla flavor en axel och Gradle väljer bara en flavor från alla (man kan inte ha free+us och paid+eu som separata varianter).

Hur åsidosätter jag applicationId för en variant?

I productFlavor- eller buildType-blocket anger du applicationId. Till exempel för free-versionen: free { applicationId "com.example.app.free" }. I manifestet använder du ${applicationId} — Gradle ersätter automatiskt värdet. Detta gör det möjligt att installera båda varianterna på en enhet.

Kan Build Variants användas i iOS?

I iOS är motsvarigheten till Build Variants kombinationen Scheme + Configuration. Xcode Schemes konfigureras via Debug/Release-konfigurationer med olika parametrar. För flera versioner (free/paid) används Build Configurations och Preprocessor Macros. I Android är konceptet mer formaliserat och inbyggt i Gradle.

Påverkar Build Variant APK-storleken?

Ja, varje variant kan ha olika APK-storlek. Debug-byggen innehåller felsökningsinformation, SDK och ej stödda resurser. Release-byggen med minifiering och resursminskning ger minimal storlek. Product Flavor påverkar också: free-versionen utan betalda bibliotek blir mindre än paid-versionen med storleken på dessa bibliotek.

Sammanfattning

  • Build Variant — kombination av en Build Type och en Product Flavor som bestämmer kompileringskonfigurationen.
  • Build Type hanterar kompileringsläge (debug/release/staging) och Product Flavor produktversion (free/paid).
  • Source sets gör det möjligt att åsidosätta kod, resurser och manifest för varje kompileringsvariant.
  • VariantFilter inaktiverar onödiga kombinationer och snabbar upp Gradle-konfiguration med 30-50%.
  • Multimodulprojekt kräver synkronisering av flavor över alla moduler eller multiple variants publishing.
  • BuildConfigField och source sets — två rena sätt att anpassa beteende mellan varianter.
  • Rekommendation: skapa inte fler än 10-12 varianter i ett projekt, gruppera dimensioner meningsfullt.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också