Given the below configuration:
productFlavors {
normal {
applicationId "com.app"
}
mock {
applicationId "com.app.mock"
}
}
buildTypes {
debug {
productFlavors.normal.buildConfigField "boolean", "mockMode", "false"
productFlavors.mock.buildConfigField "boolean", "mockMode", "true"
}
release {
productFlavors.normal.buildConfigField "boolean", "mockMode", "false"
// Release should never point to mocks. Ever.
productFlavors.mock.buildConfigField "boolean", "mockMode", "false"
}
}
I would have expected BuildConfig.mockMode = true;
, however, this is the resultant build config:
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "*****";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "mock";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
// Fields from product flavor: mock
public static final boolean mockMode = false;
}
From a little investigation/debugging, I realised that if I change the value for the product flavour in the release buildType it actually updates the BuildConfig.mockMode
value, despite having mockDebug
selected as my build variant.
I already have a better solution for achieving what I want to do, so I'm just looking for an answer that helps me understand why Gradle is acting in this way based on the configuration, to help me understand more of what it is doing.
You could extract the logic to decide on the actual value of the BuildConfig field into a method of its own. That way, the DSL configuration has a single line. It looks something like this (not tested - expect syntax errors):
buildTypes {
applicationVariants.all { variant ->
variant.buildConfigField "boolean", "mockMode", mockMode(variant)
}
}
def mockMode(variant) {
//Return true or false depending on variant.buildType and variant.productFlavors
}
Fairly easy to understand once you run with this configuration:
buildTypes {
debug {
println("debug!")
}
release {
println("release!")
}
}
What you'll see in the build log is:
Information:Gradle tasks [:app:assembleOneDebug]
debug!
release!
:app:preBuild UP-TO-DATE
...
This means that all 4 lines of your code is executed, thus the only effective lines are the last 2:
productFlavors.normal.buildConfigField "boolean", "mockMode", "false"
productFlavors.mock.buildConfigField "boolean", "mockMode", "false"
Which leads to your BuildConfig
having:
public static final boolean mockMode = false;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With