How to configure build types vs. product flavors?
Well, I wouldn't specify more build types than debug
and release
in order to use different backend.
Instead, I would use some of these techniques:
- more flavors,
- custom build config fields (documentation here),
- combine multiple product flavors (documentation here).
You can access build types, build flavors and custom fields in the application code using BuildConfig
class.
Approach with simple flavors
Build types:
debug
release
Flavors:
dev
test
live
Which would result in these build variants (you don't have to use all of them):
devDebug
devRelease
testDebug
testRelease
liveDebug
liveRelease
Approach with combining multiple flavors using dimensions
Flavor dimensions:
backend
target
Build types:
debug
release
Flavors:
target
dimension:dev
test
live
backend
dimension:production
test
Which would result in these build variants (again, you don't have to use all of them):
productionDevDebug
productionDevRelease
productionTestDebug
productionTestRelease
productionLiveDebug
productionLiveRelease
testDevDebug
testDevRelease
testTestDebug
testTestRelease
testLiveDebug
testLiveRelease
Using build field
Use additional value in build types and build flavors declarations, for example:
buildConfigField "boolean", "production_backend", "false"
or
buildConfigField "String", "backend", "\"production\""
build.gradle
class Globals {
static String devDebug = "_devDebug"
static String devRelease = "_devRelease"
static String stagingQA = "_stagingQa"
static String prodRelease = "_prodRelease"
static String prodDebug = "_prodDebug"
def firstproduct = "firstproductFP"
def secondproduct = "secondproductFP"
// Product key
static String FP = "FP"
static String SP = "SP"
}
android {
buildTypes {
debug {}
qa {}
release {}
}
flavorDimensions "client", "backend"
productFlavors {
// First Product (FP)
FP_dev {
dimension 'backend'
buildConfigField("String", "TEST", "\"FP_dev\"")
}
FP_staging {
dimension 'backend'
buildConfigField("String", "TEST", "\"FP_staging\"")
}
FP_prod {
dimension 'backend'
buildConfigField("String", "TEST", "\"FP_prod\"")
}
firstproduct {
dimension 'client'
...
}
// Second Product (SP)
SP_dev {
dimension 'backend'
buildConfigField("String", "TEST", "\"SP_dev\"")
}
SP_staging {
dimension 'backend'
buildConfigField("String", "TEST", "\"SP_staging\"")
}
SP_prod {
dimension 'backend'
buildConfigField("String", "TEST", "\"SP_prod\"")
}
secondproduct {
dimension 'client'
...
}
}
variantFilter {
variant ->
def needed = variant.name in [
Globals.firstproduct + Globals.FP + Globals.devDebug,
Globals.firstproduct + Globals.FP + Globals.stagingQA,
Globals.firstproduct + Globals.FP + Globals.prodRelease,
Globals.secondproduct + Globals.FP + Globals.devDebug,
Globals.secondproduct + Globals.FP + Globals.stagingQA,
Globals.secondproduct + Globals.FP + Globals.prodRelease
]
variant.setIgnore(!needed)
}
}
The approach of this solution allows to have multiple client compilations and backend environments for multiple product flavors.
What I did was to associate the development environment of the backend with the compilation of debug android, staging of the backend with qa of android and production of the backend with release of android. Bear in mind that there will be cases in which you need to debug the production environment or obfuscate the development environment, this solution allows it.
- firstproductFP_devDebug
- firstproductFP_stagingQa
- firstproductFP_prodRelease
- secondproductSP_devDebug
- secondproductSP_stagingQa
- secondproductSP_prodRelease
An example when compiling firstproductFP_devDebug:
BuildConfig.java
public static final String FLAVOR = "firstproductFP_dev";
public static final String FLAVOR_client = "firstproduct";
public static final String FLAVOR_backend = "FP_dev";
public static final String BUILD_TYPE = "debug";
It should be noted that within the scope of variantFilter{} you cannot use buildConfigField()
to compile values based on the build type and product flavor. This forces us to use flavorDimensions and a larger quantity productsFlavors. Nor can the active build variant be renamed.
IMPORTANT: The values of the variables must match the names of the products flavors
GL
Sources:
- Build Variants
- Exclude specific build variants