【问题标题】:How to create productFlavors from a json configuration file in build.gradle?如何从 build.gradle 中的 json 配置文件创建 productFlavors?
【发布时间】:2018-05-17 15:07:41
【问题描述】:

在一个android项目中,我需要构建几十个flavor,每个flavor针对不同的学校,每个flavor之间的唯一区别是app name/application id。

源代码控制下的build.gradle文件,所以我想制作一个json格式的不断变化的配置文件,所以要添加/删除一个flavor,不需要更改配置文件“build.gradle”喜欢:

[
    {"name": "school1"},
    {"name": "school2"}     
]

我的问题是如何读取此配置并动态创建 productFlavors?

【问题讨论】:

  • 这个问题很有趣,但我不明白为什么你需要这样做而不是使用静态风味?
  • Gradle 是一个 Groovy DSL。您可以使用 Groovy 解析 JSON,然后遍历您的数据数组并调用适当的 Gradle 方法来定义风格。
  • @MarcEstrada 这些学校是在网站中动态添加/删除的(这个网站也是我们开发的),我想在没有人为干预的情况下自动化整个构建过程,当然我可以直接修改 build.gradle , 但是 1. build.gradle 是在源代码控制下,如果机器和程序员都可以更改它,它可能很难维护,整个过程很糟糕:假设我想在 build.gradle 中添加一个依赖项,但首先,我必须检查 productFlavors 是否在产品环境中被修改。 2.解析/修改json文件比build.gradle容易很多
  • 太好了,这个想法真的很有趣!
  • @MarcEstrada 请检查我的答案

标签: android android-gradle-plugin


【解决方案1】:

在学习了一些groovy和gradle之后(因为我一开始真的对gradle感到很困惑),下面是简短的回答:

从此改变

{
    flavorDimensions 'school'   
    productFlavors {
        fooFlavor {
           dimension 'school'
           // more configurations
        } 
        barFlavor {
           dimension 'school'
           // more configurations
        }
    }
}

到:

{
    flavorDimensions 'school'   
    productFlavors {

        create('fooFlavor') {
           dimension 'school'
        } 
        create('barFlavor') {
           dimension 'school'
        }
    }
}

完整答案: 导入 groovy.json.JsonSlurper;

productFlavors {
    def slurper = new JsonSlurper()
    def orgs = slurper.parseText(new File('../orgs.json').text)
    for (org in orgs) {
        create(org.domain) {
            dimension 'org'
            applicationIdSuffix ".${org.domain}"
            resValue 'string', 'app_name', "${org.name} School"
            // add a meta-data in your AndroidManifest.xml like
            <meta-data android:name="SERVER_PREFIX" android:value="${SERVER_PRERIX}" />
            manifestPlaceholders.SERVER_PREFIX = "http://${org.domain}.xxxx.com"
        }
    }
}

以下是解释:

背景知识

build.gradle 是一个用 groovy 编写的 dsl,productFlavors 是一个闭包(但仅在 groovy 中,与闭包在 javascript 等中的含义不同。您可以粗略地认为它是一个函数),下面是一个groovy的闭包示例:

def closure = { a -> "hello, $a" }
// or, just using it (stands for the argument whatever it is)
// def closure = { "hello, $it" }
assert closure('world') == 'hello, world'

并且闭包有一个重要的内置属性delegate,这意味着你可以委托其他一些事情来执行,下面是一个例子:

def cl = { greet() } // you may wonder where's greet

class Greeter {
    public greet() { println 'hello' }
}  
// delegate to a greeter
cl.rehyderate(new Greeter(), this, this)
cl() // 'hello'

groovy 可以删除方法调用中的括号(您可能会在 coffeescript 中看到它)。这是一个例子:

def f(a, b, c) {
    a + b + c // omit return just like coffeescript
}

assert f(1, 2, 3) == 6
assert f(1) 2 3 == 6

所以前面的代码是一样的:

 {
    flavorDimensions('school')   
    productFlavors({
        create('fooFlavor', {
           dimension('school') // this is not a configuration, but just a plain method call
        })
        create('barFlavor', {
           dimension('school')
        })
    })
}

这里 productFlavors 接受一个闭包作为参数,它 delegate NamedDomainObjectContainer 来执行这个闭包,而 NamedDomainObjectContainer 有一个方法 create 来创建一个风味

【讨论】:

  • 很好的调查!!恭喜
猜你喜欢
  • 2017-07-17
  • 1970-01-01
  • 1970-01-01
  • 2018-11-25
  • 1970-01-01
  • 2019-12-04
  • 1970-01-01
  • 2020-09-14
  • 2013-06-30
相关资源
最近更新 更多