gradle 闭包实现动态赋值

背景:需要在某个闭包里面写对应的productFlavor的对应实现闭包。动态赋值,
猜想

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
//最终目标,但实现不了,原因看完全文
dependencies {
'123' {

}
'456' {

}
}
2、这样也实现不了,原因是xxx不是顶层,扩展类实现不了
dependencies {
xxx(
'123' {

}
'456' {

}
}
}
3、只能这样实现, xxx是一个方法来的
dependencies {
xxx('123') {

}
xxx('456') {

}
}

1、
build.gradle 如果要实现在root写上,如下,但解决不了问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

xxx { //自定义
yyy {
"123" {
}
"456" {
}
}
}

android {
}

dependencies {

}

方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class YYYObj {

String name

public XXXObj(String name) {
this.name = name
}
}

//创建一个扩展
class YYYExtension {

NamedDomainObjectContainer<YYYObj> testDomains

public YYYExtension(Project project) {
NamedDomainObjectContainer<YYYObj> domainObjs = project.container(YYYObj)
testDomains = domainObjs
}

//让其支持 Gradle DSL 语法
void yyy(Action<NamedDomainObjectContainer<YYYObj>> action) {
action.execute(testDomains)
}
}

getExtensions().create("xxx", YYYExtension, project) //这句话是实现在root有一个xxx的关键,这个名字不能是已经存在的,如dependencies,android等

xxx {
yyy {
"123" {

}
"456" {

}
}
}

2、下面这种写法解决了我的问题,并且优雅还过得去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
以下两个写法等价
def equalCurrentFlavorRun = {
flavor, closure ->
if (getCurrentFlavorName().toLowerCase() == flavor.toLowerCase()) {
closure(flavor)
}

}

def equalCurrentFlavorRun(String flavor, Closure closure) {
if (getCurrentFlavorName().toLowerCase() == flavor.toLowerCase()) {
closure(flavor)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 获取当前的flavor名字,得到小写的flavor
def getCurrentFlavorName() {
Gradle gradle = getGradle()
String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
Pattern pattern
if (tskReqStr.contains("assemble"))
pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
else if (tskReqStr.contains("channel"))
pattern = Pattern.compile("channel(\\w+)(Release|Debug)")
else
pattern = Pattern.compile("generate(\\w+)(Release|Debug)")

Matcher matcher = pattern.matcher(tskReqStr)

if (matcher.find())
return matcher.group(1).toLowerCase()
else
return ""

}

后面实现就是这样

1
2
3
4
5
6
7
8
9
10
11
12
dependencies {
//公共的写在这里
testImplementation 'junit:junit:4.12'
equalCurrentFlavorRun("xxx") {
//xxx马甲包单独的
implementation 'androidx.core:core-ktx:1.1.0'
}
equalCurrentFlavorRun("yyy") {
//yyy马甲包单独的
implementation 'androidx.core:core-ktx:1.0.2'
}
}