I have three flavors:
flavorDimensions += listOf("flavour_1", "flavour_2")
productFlavors {
create("Flavour1") {
applicationId = "com.pkg.flavour_1"
dimension = "flavour_1"
}
create("Flavour2") {
applicationId = "com.pkg.flavour_2"
dimension = "flavour_1"
}
create("Flavour3") {
applicationId = "com.pkg.flavour_3"
dimension = "flavour_2"
}
}
sourceSets {
getByName("Flavour1") {
res.srcDirs("src/Flavour1/res")
java.srcDirs("src/Flavour1/java")
}
getByName("Flavour2") {
res.srcDirs("src/Flavour2/res")
java.srcDirs("src/Flavour2/java")
}
}
and I don't understand why I can not find options for adding source folders for Flavour2, only for Flavour1 and Flavour3. I think it is because of different and commong dimension. If yes, so I don't understand for which purpose we need to use common dimension. Also another question is how is it correct to create several MainActivity files for different flavors. I saw several sources which say that when we have flavors we have to remove all .kt classes from main
root. But in such case the main manifest will be broken. At this moment I managed only to create separate build variants for that flavors.
Okay, since you want three flavors, it makes it a bit easier - you need only 1 dimension.
flavorDimensions
are not productFlavors
.
Think of dimensions
as Spinners where created flavors
are the items in the spinner.
flavorDimensions += listOf("brand")
productFlavors {
create("Brand1") {
...
dimension = "brand"
}
create("Brand2") {
...
dimension = "brand"
}
create("Brand3") {
...
dimension = "brand"
}
}
That was basically it, just remove the second dimension.
sourceSets {
getByName("Brand1") {
res.srcDirs("src/Brand1/res")
java.srcDirs("src/Brand1/java")
}
getByName("Brand2") {
res.srcDirs("src/Brand2/res")
java.srcDirs("src/Brand2/java")
}
getByName("Brand3") {
res.srcDirs("src/Brand3/res")
java.srcDirs("src/Brand3/java")
manifest.srcFile("src/Brand3/AndroidManifest.xml")
}
}
The following bit assumes your original code - flavorDimensions += listOf("flavour_1", "flavour_2")
What was happening was that Gradle was trying to create all possible variations of product dimensions - the order matters. With your dimensions, Gradle will try to create variants in this manner.
flavor_1 * flavor_2 * buildTypes(debug/release)
Resulting in:
Flavour1 * Flavour3 * Debug
Flavour2 * Release
Now regarding sources. You don't have to remove everything from main source root, only the sources specific for the flavor("BrandX") - typically it is going to be stuff like UI elements and logic that are not common. With properly defined source sets the sequence of putting classes together is:
main -> flavour_1 -> flavour_2 -> releaseType
flavour_2
can utilize anything that comes from flavour_1
- as long as the signature is the same.
Also, you can have source directories that explicitly define the combination of flavors/dimensions - even without explicitly defining them as source sets. e.g. "src/Brand1Brand2/java"
. (Note: this assumes 2+ dimensions)
As mentioned, Android Studio doesn't automatically generate source folders for you, you have to create them manually.
Regarding AndroidManifest files, each flavor can have its own - they end up merged into one but that's also a quite long topic and out of the scope of this question. To define the flavor version, just add manifest.srcFile()
to the source set for the flavor.
How you end up separating the source code will eventually be up to you. From my experience, it relied heavily on Default/Base classes for UI and hiding logic behind interfaces which each flavor source set was providing through their module for dependency injection(DI/Hilt).