⚠ Created by ChatGPT πŸ€–

In Android Gradle, these four conceptsβ€”Flavor, Dimension, Build Type, and Variantβ€”work together to generate different versions of your app (for example: free vs paid, dev vs prod). Below is a clear explanation with Kotlin DSL (build.gradle.kts) examples.


1. Build Type

A Build Type defines how the app is built (debugging, optimization, signing).

Android already provides two default types:

  • debug
  • release

Example (Kotlin DSL)

android {
    buildTypes {
        getByName("debug") {
            isDebuggable = true
            applicationIdSuffix = ".debug"
        }

        getByName("release") {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

Result

Two builds:

app-debug.apk
app-release.apk

Typical usage:

  • debug β†’ development/testing
  • release β†’ production

2. Product Flavor

A Flavor defines different versions of the app itself.

Example:

  • free vs paid
  • dev vs production server
  • googlePlay vs amazon store

Example

android {
    productFlavors {

        create("free") {
            applicationIdSuffix = ".free"
            versionNameSuffix = "-free"
        }

        create("paid") {
            applicationIdSuffix = ".paid"
        }
    }
}

Result

freeDebug
freeRelease
paidDebug
paidRelease

Each flavor can have:

  • different API URLs
  • different features
  • different app icons

3. Flavor Dimension

A Dimension groups flavors into categories.

Why? Because Gradle allows multiple flavor categories.

Example categories:

  • environment
  • tier

Example

tier: free / paid
environment: dev / prod

Kotlin DSL

android {

    flavorDimensions += listOf("tier", "environment")

    productFlavors {

        create("free") {
            dimension = "tier"
        }

        create("paid") {
            dimension = "tier"
        }

        create("dev") {
            dimension = "environment"
            applicationIdSuffix = ".dev"
        }

        create("prod") {
            dimension = "environment"
        }
    }
}

Generated combinations

freeDevDebug
freeDevRelease
freeProdDebug
freeProdRelease
paidDevDebug
paidDevRelease
paidProdDebug
paidProdRelease

This is extremely powerful for large apps.


4. Build Variant

A Variant = Flavor(s) + Build Type

Formula:

Variant = ProductFlavor(s) + BuildType

Example:

FlavorBuild TypeVariant
freedebugfreeDebug
freereleasefreeRelease
paiddebugpaidDebug
paidreleasepaidRelease

With dimensions:

paidProdRelease
freeDevDebug

5. Folder Structure for Variants

Android lets you override code/resources per flavor or variant.

Example:

src/
 β”œ main/
 β”‚   β”” java/
 β”œ debug/
 β”‚   β”” java/
 β”œ free/
 β”‚   β”” java/
 β”œ freeDebug/
 β”‚   β”” java/
 β”œ dev/
 β”‚   β”” java/

Priority order:

variant > flavor > buildType > main

Example:

src/freeDebug/java

overrides everything.


6. Real Example (API environments)

android {

    flavorDimensions += "environment"

    productFlavors {

        create("dev") {
            dimension = "environment"

            buildConfigField(
                "String",
                "BASE_URL",
                "\"https://dev.api.com\""
            )
        }

        create("prod") {
            dimension = "environment"

            buildConfigField(
                "String",
                "BASE_URL",
                "\"https://api.com\""
            )
        }
    }
}

Usage in Kotlin:

val baseUrl = BuildConfig.BASE_URL

7. Visual Summary

                    +--------------+
                    |  Build Type  |
                    | debug/release|
                    +--------------+
                           |
                           |
              +----------------------------+
              |        Product Flavor       |
              | free / paid / dev / prod    |
              +----------------------------+
                           |
                           |
                    +-------------+
                    |   Variant   |
                    | freeDebug   |
                    | paidRelease |
                    +-------------+

8. Example Full build.gradle.kts

android {

    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.app"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
    }

    buildTypes {
        debug {
            applicationIdSuffix = ".debug"
        }

        release {
            isMinifyEnabled = true
        }
    }

    flavorDimensions += "tier"

    productFlavors {

        create("free") {
            dimension = "tier"
        }

        create("paid") {
            dimension = "tier"
        }
    }
}

Variants generated:

freeDebug
freeRelease
paidDebug
paidRelease

βœ… Quick Memory Trick

Build Type β†’ HOW the app is built
Flavor β†’ WHAT version of the app
Dimension β†’ CATEGORY of flavors
Variant β†’ FINAL combination