Mobile Development 9 min read

Gradle Product Flavors for Multi‑Channel Android Packaging

This article explains how to use Gradle's productFlavors, flavorDimensions, variant filters, signing configurations, manifest placeholders and source‑set priorities to create flexible multi‑channel Android builds, comparing fast simple packaging with a fully customizable approach and providing command‑line examples.

Qunar Tech Salon
Qunar Tech Salon
Qunar Tech Salon
Gradle Product Flavors for Multi‑Channel Android Packaging

When building Android apps you often need to generate multiple channel packages. Two main strategies exist: a quick solution that only changes a channel identifier, and a more flexible approach using Gradle's productFlavors to customize code, resources, dependencies, and signing per channel.

Configuration : In the module's build.gradle define a flavor dimension and product flavors, e.g.:

android {
    flavorDimensions "channel"
    productFlavors {
        common {
            dimension "channel"
        }
        xiaomi {
            dimension "channel"
            minSdkVersion 21
            versionCode 20000 + defaultConfig.versionCode
            versionNameSuffix "-minApi21"
        }
        huawei {
            dimension "channel"
            minSdkVersion 23
            versionCode 20000 + defaultConfig.versionCode
            versionNameSuffix "-minApi23"
        }
    }
    buildTypes {
        debug { minifyEnabled false }
        release { minifyEnabled false }
    }
}

Gradle will generate build variants for each combination of flavor and build type, e.g. app-[common,xiaomi,huawei]-[debug,release].apk .

Variant Filtering : Use variantFilter to exclude unwanted variants, for example removing commonDebug :

android {
    variantFilter { variant ->
        def names = variant.flavors*.name
        def buildTypeName = variant.buildType.name
        if (buildTypeName.contains("debug") && names.contains("common")) {
            setIgnore(true)
        }
    }
}

Dependencies : Declare channel‑specific dependencies, such as:

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:26.1.0"
    xiaomiDebugImplementation "com.xxx:xxx:1.6.0"
    debugImplementation "com.xxx:xxx:1.6.0"
    commonImplementation "com.xxx:xxx:1.6.0"
}

Signing Configs : Define separate keystores for each channel and assign them in the release build type:

signingConfigs {
    test11 {
        storeFile file("../test11.keystore")
        storePassword "test11"
        keyAlias "test11"
        keyPassword "test11"
    }
    test22 {
        storeFile file("../test22.keystore")
        storePassword "test22"
        keyAlias "test22"
        keyPassword "test22"
    }
}
android {
    buildTypes {
        release {
            productFlavors.huawei.signingConfig signingConfigs.test11
            productFlavors.xiaomi.signingConfig signingConfigs.test22
        }
    }
}

Manifest Placeholders : Use manifestPlaceholders to replace icons, activity names, and meta‑data per flavor:

productFlavors {
    common {
        manifestPlaceholders = [
            ChannelData: "Common Meta Data",
            AppIcon: "@mipmap/ic_common",
            MainActivity: "CommonActivity"
        ]
    }
    xiaomi {
        manifestPlaceholders = [
            ChannelData: "XiaoMiMetaData",
            AppIcon: "@mipmap/ic_launcher",
            MainActivity: "XMActivity"
        ]
    }
    huawei {
        manifestPlaceholders = [
            ChannelData: "HuaWeiMetaData",
            AppIcon: "@mipmap/ic_launcher",
            MainActivity: "HWActivity"
        ]
    }
}

Source‑Set Priority : Gradle merges resources and code from source sets in the order commonDebug → debug → common → main . Files in higher‑priority sets override those in lower ones, allowing channel‑specific assets, strings, and Java classes without duplication errors.

Command‑Line Build : Common Gradle commands include gradle assemble (all), gradle assembleDebug , gradle assembleRelease , gradle assembleXiaomiDebug , and gradle installXiaomiDebug . Use gradle clean before testing.

For further reading see the official Android documentation and related blog posts.

AndroidGradleSigningBuildConfigMultiChannelProductFlavors
Qunar Tech Salon
Written by

Qunar Tech Salon

Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.