Sometimes some fetaures of your app must behave differently for different flavors o build type. Think about when you need to enable logging for a specific flavor only, or you have to disable crash reporting for your “dev build”. All this behaviours can be configured at compile time, insted of using many if/else blocks that are evaluated at runtime.
In the following example I’ll use Gradle and Dagger.
First step: create an interface CrashReporter
and two implementations: CrashReporterRealImpl
and CrashReporterNullImpl
.
Second step: configure the build.gradle
file for our app.
android {
// constants
def BOOLEAN = "boolean"
def TRUE = "true"
def FALSE = "false"
// app features
def FEATURE_CRASH_REPORTING_ENABLED = "FEATURE_CRASH_REPORTING_ENABLED"
...
defaultConfig {
...
// default features
buildConfigField BOOLEAN, FEATURE_CRASH_REPORTING_ENABLED, FALSE
}
productFlavors {
developer {
...
}
qateam {
...
}
playstore {
...
buildConfigField BOOLEAN, FEATURE_CRASH_REPORTING_ENABLED, TRUE
}
}
}
Third step: use dagger to provide the right instance of CrashReporter
.
Final step: inject and use!
It could seem a lot of code for just enabling/disabling a feature, but with this approach the code is modular (for example you could easily replace CrashReporterRealImpl with another one that uses another service, or you can temporarly enable crash reporting for another flavor for testing purposes) and there’s no logic that needs to be tested.
With this approach you could also develop new functions directly in the master branch without using a “feature branch”.
Suppose that we have to work on our new feature called “Experimental Feature”. We just need to create an interface and two implementations as done before:
Then create the definitions in build.gradle and add provide method to the dagger module:
Now we can continue to develop in the master branch and commit even when our ExperimentalFeatureControllerRealImpl
does not work correctly: FEATURE_EXPERIMENTAL_ENABLED will be TRUE only for our “dev build”, and in FALSE for production build.
When ExperimentalFeatureControllerRealImpl
will be ready for production, we will just have to set FEATURE_EXPERIMENTAL_ENABLED to TRUE also for production build!