Our application has a free and a paid version. We also make branded-versions, which means that the application vary in two dimensions.
Four versions could be:
My solution now is to have two build-types, paid and free:
buildTypes {
paid {
packageNameSuffix ".paid"
}
free {
packageNameSuffix ".free"
}
}
And two build flavors:
productFlavors{
nike{
packageName "com.example.theapp.nike"
}
adidas{
packageName "com.example.theapp.adidas"
}
}
Every free-version of the app make us of a content-provider, a content provider which is specific per flavor-build type combination. The problem is that I don't understand where to put a source file based on build variant. Source files put into /src/nike or /src/free will be picked up depending on build type or flavor. But how about source files that are depending on the build variant (the combination of type and flavor)?
gradle files in an Android Studio project?
Each module has its own build file, so every Android Studio project contains two kinds of Gradle build files.
You can do this by adding extra properties to the ext block in the top-level build.gradle file. // of properties you can define. // You can also create properties to specify versions for dependencies.
Build variants are the result of Gradle using a specific set of rules to combine settings, code, and resources configured in your build types and product flavors. Although you do not configure build variants directly, you do configure the build types and product flavors that form them.
You can create a new folder under src for every build or flavor that you have. i.e: 'free', 'paid', 'nike', 'adidas'.
The files that you put in any of these folders gets picked up when building depending on the type and build both.
According to Gradle Plugin User Guide on Android Tools Project Site:
Similar to Build Types, Product Flavors also contribute code and resources through their own sourceSets.
and
The following rules are used when dealing with all the sourcesets used to build a single APK:
- All source code (src/*/java) are used together as multiple folders generating a single output.
- Manifests are all merged together into a single manifest. This allows Product Flavors to have different components and/or permissions, similarly to Build Types.
- All resources (Android res and assets) are used using overlay priority where the Build Type overrides the Product Flavor, which overrides the main sourceSet.
- Each Build Variant generates its own R class (or other generated source code) from the resources. Nothing is shared between variants.
meaning that your java files for the buildType "free" will overwrite the ones for your flavors "nike" if they have the same name.
But if you're adding something to a manifest, according to the second point in the list above the final manifest will be a merge of all of the manifests.
If you need more customization you can put your files in your build variant's folder "src/freeNike/".
I had similar problem with build types overriding flavors due to the overlay rules.
I ended up redirecting the build type source sets into different folders depending on which flavor was built.
android.applicationVariants.all { variant ->
switch (variant.name) {
case "FreeNike":
variant.mergeResources.doFirst {
android.sourceSets.free.setRoot("src/freeNike")
}
break;
case "FreeAdidas":
variant.mergeResources.doFirst {
android.sourceSets.free.setRoot("src/freeAdidas")
}
break;
case "PaidNike":
variant.mergeResources.doFirst {
android.sourceSets.paid.setRoot("src/paidNike")
}
break;
case "PaidAdidas":
variant.mergeResources.doFirst {
android.sourceSets.paid.setRoot("src/paidAdidas")
}
break;
}
}
You are of course free to use a different folder structure. See example here: Folder naming convention for gradle build variants
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