Dynamically generating product flavors

南笙酒味 提交于 2019-11-28 04:25:09

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
            }
        }
    }

}

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:

  • Would also like to add, the com.mypackagename is basically the root path for all flavors.
  • I have a separate script that copy-pastes the a flavor directory to the /app/src/ folder.

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!.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!