From the Google User Guide
Multiple Flavor Options
In some cases, you may need to create several versions of the same applications based on several criteria. For example, multi-apk support on Google Play supports 4 different filters. Creating a different APK division for each filter requires the ability to use more than one product size.
Consider an example of a game with a demo version and a paid version, wants to use the ABI filter in multi-apk support. With 3 ABIs and two versions of the application, you need to create 6 APKs (not counting the options introduced by the different build types). However, the paid version code is the same for all three ABIs, so creating only 6 flavors is not an option. Instead, there are two dimensions of tastes, and options should automatically build all possible combinations.
This feature is implemented using Flavor Dimensions. Flavors assigned to a specific android size {...
flavorDimensions "abi", "version" productFlavors { freeapp { flavorDimension "version" ... } x86 { flavorDimension "abi" ... } } }
flavorGroups been replaced with flavorDimensions , so you need to use the following code in build.gradle
// 2 dimensions of flavors. API is more important than ABI. flavorDimensions "api", "abi" productFlavors { gingerbread { flavorDimension "api" minSdkVersion 10 versionCode = 1 } icecreamSandwich { flavorDimension "api" minSdkVersion 14 // this must be higher than the gingerbread version to ensure update of the // app when the device gets a system update from GB to ICS versionCode = 2 } x86 { flavorDimension "abi" ndk.abiFilter "x86" // this is the flavor part of the version code. // It must be higher than the arm one for devices supporting // both, as x86 is preferred. versionCode = 3 } arm { flavorDimension "abi" ndk.abiFilter "armeabi-v7a" versionCode = 1 } mips { flavorDimension "abi" // It must be higher than the arm one for devices supporting // both, as mips is preferred. ndk.abiFilter "mips" versionCode = 2 } fat { flavorDimension "abi" // fat binary, lowest version code to be // the last option versionCode = 0 } } // make per-variant version code applicationVariants.all { variant -> // get the version code of each flavor def apiVersion = variant.productFlavors.get(0).versionCode def abiVersion = variant.productFlavors.get(1).versionCode // set the composite code variant.mergedFlavor.versionCode = apiVersion * 1000000 + abiVersion * 100000 + defaultConfig.versionCode }
Update:
Add these lines to be able to see versionCode with generated apk names
applicationVariants.all { variant -> variant.outputs.each { output -> def apk = output.outputFile; def newName = "${output.name}-${variant.mergedFlavor.versionCode}" if (variant.buildType.versionNameSuffix) { newName += "-${variant.buildType.versionNameSuffix}" } if (output.zipAlign) { output.zipAlign.outputFile = new File((File) apk.parentFile, newName + '-aligned.apk'); } output.packageApplication.outputFile = new File((File) apk.parentFile, newName + ".apk") } }
See the following build result:
gingerbreadArmDebug-1100123.apk gingerbreadArmDebug-1100123-aligned.apk gingerbreadFatDebug-1000123.apk gingerbreadFatDebug-1000123-aligned.apk gingerbreadMipsDebug-1200123.apk gingerbreadMipsDebug-1200123-aligned.apk gingerbreadX86Debug-1300123.apk gingerbreadX86Debug-1300123-aligned.apk icecreamSandwichArmDebug-2100123.apk icecreamSandwichArmDebug-2100123-aligned.apk icecreamSandwichFatDebug-2000123.apk icecreamSandwichFatDebug-2000123-aligned.apk icecreamSandwichMipsDebug-2200123.apk icecreamSandwichMipsDebug-2200123-aligned.apk icecreamSandwichX86Debug-2300123.apk icecreamSandwichX86Debug-2300123-aligned.apk gingerbreadArmRelease-1100123.apk gingerbreadFatRelease-1000123.apk gingerbreadMipsRelease-1200123.apk gingerbreadX86Release-1300123.apk icecreamSandwichArmRelease-2100123.apk icecreamSandwichFatRelease-2000123.apk icecreamSandwichMipsRelease-2200123.apk icecreamSandwichX86Release-2300123.apk
Information from one of them extracted by apktool :
version: 2.0.0-RC3 apkFileName: gingerbreadArmDebug-1100123.apk isFrameworkApk: false usesFramework: ids: - 1 sdkInfo: minSdkVersion: '10' targetSdkVersion: '21' packageInfo: forced-package-id: '127' versionInfo: versionCode: '1100123' versionName: '1.0' compressionType: false
Update 2:
Published my test project on GitHub