Dynamically generating product flavors

后端 未结 3 1261
南旧
南旧 2020-12-07 23:16

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

相关标签:
3条回答
  • 2020-12-07 23:55

    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
                }
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-12-08 00:08

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

    0 讨论(0)
  • 2020-12-08 00:17

    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.
    0 讨论(0)
提交回复
热议问题