I\'ve created an Android App which needs to be build in many (30+) flavors.
My idea was to generate the different productFlavors
directly from the folde
Solved by trial and error:
android {
// let's assume these are return by a function which reads the filesystem
def myFlavors = [
flavor1: [
packageName: "com.example.flavor1"
],
flavor2: [
packageName: "com.example.flavor2"
]
]
productFlavors {
myFlavors.each { name, config ->
"$name" {
packageName config.packageName
}
}
}
}
Since the question author didn't want to share his code for reading files. I'm gonna write about what I did. I put all the variants name in a file named "app/build_variants.txt", one line for each, something like this:
flavor1
flavor2
flavor3
flavor4
flavor5
And in "app/build.gradle":
//...other configs...
android {
productFlavors {
new File('app/build_variants.txt').eachLine { "$it" { resValue "string", "build_variant_name", "$it" } }
}
}
//...other configs
This will have the same result as the following code:
//...other configs...
android {
productFlavors {
flavor1 { resValue "string", "build_variant_name", "flavor1" }
flavor2 { resValue "string", "build_variant_name", "flavor2" }
flavor3 { resValue "string", "build_variant_name", "flavor3" }
flavor4 { resValue "string", "build_variant_name", "flavor4" }
flavor5 { resValue "string", "build_variant_name", "flavor5" }
}
}
//...other configs
The key here is the line new File('app/build_variants.txt').eachLine { "$it" { resValue "string", "build_variant_name", "$it" } }
. It reads the file 'app/build_variants.txt' and for each line, generate a product flavor with the name in the line it reads. the $it
is the line it passes in. It just groovy's closure syntax. If you want a deeper understanding. I strongly recommend watching @Daniel Lew's video about groovy and gradle. It's awesome!.
I know there's already an answer for this, but I kind of combined Chris.Zou's approach with TheHippo. And add my own method for doing this.
Basically, when dealing with flavors, we normally work with different directories under /app/src/ which contains resources. And since the directory name is equal to the package name, I simply listed the directories under that folder (excluded "main" and "androidTest").
So here's my complete, working gradle script:
def map = [:]
new File("./app/src").eachFile() { file->
def fileName = file.getName()
if( fileName == "main" || fileName == "androidTest") {
return
}
map.put(fileName, 'com.mypackagename.' + fileName )
}
productFlavors {
map.each { flavorName, packagename ->
"$flavorName" {
applicationId packagename
}
}
}
Edit: