在学习了一些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 来创建一个风味