I have the following flavours configuration in an Android project:
android {
buildTypes {
release { }
debug { }
}
flavorDimensions "fruit", "color"
productFlavors {
apple {
dimension "fruit"
}
peach {
dimension "fruit"
}
banana {
dimension "fruit"
}
red {
dimension "color"
}
green {
dimension "color"
}
yellow {
dimension "color"
}
}
}
dependencies {
appleRedImplementation 'com.apple:color_red:1.1.0'
appleGreenImplementation 'com.apple:color_green:1.1.0'
appleYellowImplementation 'com.apple:color_yellow:1.1.0'
// No dependency for other fruit build type
}
I need to keep the com.apple:color_*:1.1.0 dependency only for the apple flavorDimensions builds, but change it based on the color flavorDimensions builds?
If you want to add dependencies to specific configurations of multiple build flavor dimensions, you need to define those combinations first:
android{
...
productFlavors {
...
}
configurations {
appleRedImplementation {}
appleGreenImplementation {}
appleYellowImplementation {}
}
}
This answer here references this as well: https://stackoverflow.com/a/60776044/2258611
Related
For example, There is a dependency ZZZ, and 6 flavors flavor1, flavor2, ... , flavor6.
If only want flavor1 add the dependency, I can use this:
dependencies {
flavor1Implementation `ZZZ`
}
But if I want all flavors except flavor1 to add this dependency, like this:
dependencies {
flavor2Implementation `ZZZ`
flavor3Implementation `ZZZ`
flavor4Implementation `ZZZ`
flavor5Implementation `ZZZ`
flavor6Implementation `ZZZ`
}
It's a disaster when I have many flavors...
Is there a better way to do this?
One option will be to use variantFilter, for instance:
android {
productFlavors {
flavor1 {
}
flavor2 {
}
flavor3 {
}
...
}
variantFilter { variant ->
if (!variant.flavors.name.contains("flavor1")) {
var nameVariant = variant.flavors.name[0]
getDependencies().add("${nameVariant}Implementation", "ZZZ")
}
}
}
With variantFilter you can loop through each combination between buildTypes and productFlavors, avoiding to add dependencies on flavor1 and add the required dependencies programmatically in all the others.
Hope this helps
It is in android gradle build scripts. I have multiple flavors in gradle:
flavorDimensions "brand", "appVariant"
productFlavors {
stage {
dimension "appVariant"
}
prod {
dimension "appVariant"
}
brand1 {
dimension "brand"
}
brand2 {
dimension "brand"
}
}
How can I rewrite that using kotlin-dsl?
This will work:
flavorDimensions("brand", "appVariant")
productFlavors {
create("var1") {
setDimension("appVariant")
}
create("var2") {
setDimension("appVariant")
}
create("brand1") {
setDimension("brand")
}
create("brand2") {
setDimension("brand")
}
}
Can I do that?
I have following setup:
buildTypes {
debug {
// ...
}
release {
// ...
}
productFlavors {
flavorDimensions "buildType", "versionType"
fastBuild {
minSdkVersion 21
dimension "buildType"
}
regular {
minSdkVersion setup.minSdk
dimension "buildType"
}
free {
dimension "versionType"
}
pro {
applicationIdSuffix ".premium"
dimension "versionType"
}
}
This combines to 8 build variants. Actually I only need following 3:
fastBuildDebugPro (my test build)
regularBuildFreeRelease
regularBuildProRelease
Can I somehow exclude the other 5 auto generated build variants?
When using Gradle flavorDimensions, is it possible to exclude specific variants?
For example -
android {
...
flavorDimensions "abi", "version"
productFlavors {
freeapp {
flavorDimension "version"
...
}
x86 {
flavorDimension "abi"
...
}
}
the following build variants will be created:
x86-freeapp-debug
x86-freeapp-release
arm-freeapp-debug
arm-freeapp-release
mips-freeapp-debug
mips-freeapp-release
x86-paidapp-debug
x86-paidapp-release
arm-paidapp-debug
arm-paidapp-release
mips-paidapp-debug
mips-paidapp-release
Can "mips-paidapp-release" be manually removed?
Since Gradle 0.9 you can apply a variant filter and iterate over them:
productFlavors {
freeapp {
dimension "version"
}
x86 {
dimension "abi"
}
paidapp {
dimension "mips"
}
}
// Loop variants
android.variantFilter { variant ->
// Loop flavors
variant.getFlavors().each { flavor ->
println variant.buildType.name + " " + flavor.name + " " + flavor.dimension
if (variant.buildType.name.equals('release') &&
flavor.name.equals('paidapp') &&
flavor.dimension.equals('mips')) {
variant.setIgnore(true)
}
}
}
Note: that I changed flavorDimension to dimension because the latter is now the preferred way specify it.
Note2: the above note requires you to use the newer gradle version:
Project/build.gradle should have the following:
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
while Project/app/build.gradle should have this:
android {
buildToolsVersion "22.0.1"
...
}
This is how I do it:
flavorDimensions "device", "server"
productFlavors {
emulator {
dimension = "device"
}
phone {
dimension = "device"
}
staging {
dimension = "server"
}
production {
dimension = "server"
}
}
android.variantFilter { variant ->
def device = variant.getFlavors().get(0).name
def server = variant.getFlavors().get(1).name
def isRelease = variant.buildType.name.equals('release')
def isDebug = variant.buildType.name.equals('debug')
// Disable emulatorProductionRelease build variant
if (device.equals('emulator') && server.equals('production') && isRelease) {
variant.setIgnore(true)
}
}
I like it because it's easy to read and you can target specific build variants.
I'm trying to figure out how can I specify a signingConfig for the individual flavor dimensions generated. I have seen how to do it when using different flavor but not flavor dimensions.
I'm currently applying a different package name for the different flavor dimensions successfully and thought maybe something similar could be done with signingConfig?
> android.applicationVariants.all { variant ->
> def flavorString = variant.getVariantData().getVariantConfiguration().getFlavorName()
> def mergedFlavour = variant.getVariantData().getVariantConfiguration().getMergedFlavor();
>
> if(flavorString.equalsIgnoreCase("amazonFree")) {
> mergedFlavour.setApplicationId("com.test.amazon.free")
> }
> if(flavorString.equalsIgnoreCase("amazonPro")) {
> mergedFlavour.setApplicationId("com.test.amazon.pro")
> }
> if(flavorString.equalsIgnoreCase("googleFree")) {
> mergedFlavour.setApplicationId("com.test.google.free")
> }
> if(flavorString.equalsIgnoreCase("googlePro")) {
> mergedFlavour.setApplicationId("com.test.google.pro")
> } }
My flavor setup
// Special flavor dimensions for different markets and
// versions paid and free.
flavorDimensions 'market', 'version'
productFlavors {
amazon {
flavorDimension 'market'
}
google {
flavorDimension 'market'
}
// Base free version
free {
flavorDimension 'version'
// Need this cause of all the ad libraries we are using :/
defaultConfig.multiDexEnabled true
// For now we sign all free versions with this config
// cause we have no idea how to sign the individual flavor dimensions.
signingConfig signingConfigs.googleFree
}
// Base pro version
pro {
flavorDimension 'version'
// For now we sign all free versions with this config
// cause we have no idea how to sign the individual flavor dimensions.
signingConfig signingConfigs.googlePro
}
}
First of all applicationId can be applied in productFlavors block itself:
productFlavors {
amazonFree {
applicationId 'com.test.amazon.free'
}
amazonPro {
applicationId 'com.test.amazon.pro'
}
googleFree {
applicationId 'com.test.google.free'
}
googlePro {
applicationId 'com.test.google.pro'
}
}
Signing config can be configured per flavor the same way:
productFlavors {
amazonFree {
applicationId 'com.test.amazon.free'
signingConfig signingConfigs.amazonFree
}
amazonPro {
applicationId 'com.test.amazon.pro'
signingConfig signingConfigs.amazonPro
}
googleFree {
applicationId 'com.test.google.free'
signingConfig signingConfigs.googleFree
}
googlePro {
applicationId 'com.test.google.pro'
signingConfig signingConfigs.googlePro
}
}
When you start using flavorDimensions the best solution to set signingConfig for different variants is to use androidComponents block. For example:
androidComponents {
onVariants(selector().all(), { variant ->
if (variant.name == "xxyyzzGmsRelease") {
variant.signingConfig?.setConfig(signingConfigs.play_store)
} else if (variant.name == "xxyyzzHmsRelease") {
variant.signingConfig?.setConfig(signingConfigs.huawei_store)
}
})
}
Tested on Gradle 7.4 and AGP 7.3.1.