一 前言
在构建脚本中,变量主要可以分为两大类,本地变量和额外属性。这两中变量定义和使用有所不同,作用域范围也不一样。
二、本地变量
本地变量使用 def
关键字定义,本地变量只在定义它的作用域内可见,局部变量是底层Groovy语言的一个特性。
注意事项:即使在构建脚本文件的顶层定义了局部变量,也只能在当前构建脚本内访问,不能跨脚本文件引用(脚本文件被其他脚本文件引入)。
- 示例
def testLocalParam = "This is test local param"
tasks.register("testT") {
def innerParam = "Inter task param"
doFirst() {
println(testLocalParam)
println("doFirst: ${innerParam}")
}
doLast() {
println("doLast: ${innerParam}")
}
}
- 输出
E:\AndroidStudioProjects\AndroidDemo>gradlew -q testT
This is test local param
doFirst: Inter task param
doLast: Inter task param
以上示例中,testLocalParam
本地变量定义在构建脚本最外层,作用域是变量定义处以下部分脚本。而innerParam
在 Task 内部定义,作用域是 Task内部,外部无法访问。
注意事项:构建文件是脚本文件,定义的变量作用域是定义处往下,也就是只能在变量定义处下面部分脚本中引用变量,如果需要定义整个构建脚本都可以访问的局部变量,请在构建脚本文件顶部定义。
三、额外属性
在 Gradle 域模型中的所有增强型对象,都可以拥有用户自定义的额外属性,这些属性包括但不限于项目(projects)、任务(tasks)和源码集合(source sets)。额外属性可以通过所有者对象的 ext
属性进行添加、读取和赋值,使用 ext
块,可以一次性添加多个额外属性。额外属性一旦添加,就可以和预定义的属性一样读取和赋值。如下示例:
ext.testParam5 = null
ext {
testParam1 = "This is test param 1"
testParam2 = "This is test param 2"
testParam3 = "This is test param 3"
testParam4 = "This is test param 4"
}
rootProject.ext.testParam8 = "This is test param 8 added to root project"
tasks.register("testT") {
doFirst() {
println("doFirst -- testParams 1 --- ${testParam1}")
testParam5 = "This is test param 5 added from app project build script root"
project.ext.testParam6 = "This is test param 6 added from app project build script--task testT"
}
doLast() {
project.ext.properties.findAll {
return it.key.toString().startsWith("test")
}.each {
println(it)
}
}
}
- 输入结果
E:\AndroidStudioProjects\AndroidDemo>gradlew -q testT
doFirst -- testParams 1 --- This is test param 1
doLast: Inter task param
testParam1=This is test param 1
testParam2=This is test param 2
testParam3=This is test param 3
testParam4=This is test param 4
testParam5=This is test param 5 added from app project build script root
testParam6=This is test param 6 added from app project build script--task testT
从上面的示例中,我们可以总结到以下几点:
- 在脚本中可以使用
ext
块一次性添加多个额外属性,添加单个属性使用ext.paramName
的方式添加; - 额外属性在引用之前必须先添加(定义),如果引用不存在的额外属性或者拼写错误,Gradle编译将会出现找不到属性的错误;
- 引用项目内的额外属性可以直接使用属性名称,引用其他项目的属性要使用
projectName.ext.paramName
的形式(往其他项目添加额外属性同理); null
是一个合法的属性值;
额外属性可以跨文件定义,当定义额外属性的脚本文件被构建脚本引入时,将会在构建脚本所在的项目中添加这些额外属性。如下示例:
- 根项目目录中添加
config.gradle
ext {
testParam1 = "This is test param 1"
testParam2 = "This is test param 2"
testParam3 = "This is test param 3"
testParam4 = "This is test param 4"
}
- __在跟项目目录构建文件
build.gradle
引入config.gradle
__
// 引入 config.gradle
apply from: "${rootDir}/config.gradle"
buildscript {
ext.kotlin_version = "1.4.0"
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
在以上示例中, config.gradle
文件中使用 ext
块定义多个额外属性,在根项目的构建脚本 build.gradle
中引入 config.gradle
文件,因此 config.gradle
文件中定义的额外属性就成了根项目的额外属性,在根目录中可以直接使用属性名访问这些额外属性。如果在 app
子项目中引入 config.gradle
文件,那么文件中定义的额外属性就属于 app
子项目。
额外属性具有比局部变量更加宽广的作用域,在任何可以访问额外属性拥有者的地方,都可以访问这些额外属性。因此,项目的额外属性是对子项目可见的(在子项目中是可以访问父项目,因此也可以访问父项目中定义的额外属性),但是在子项目中引用父项目的额外属性,必须添加父项目前缀(rootProject.ext.
)进行引用。如下示例:
app
项目中的build.gradle
tasks.register("testT") {
doLast() {
rootProject.ext.properties.findAll {
return it.key.toString().startsWith("test")
}.each {
println(it)
}
}
}
- 执行输出
E:\AndroidStudioProjects\AndroidDemo>gradlew -q testT
testParam1=This is test param 1
testParam2=This is test param 2
testParam3=This is test param 3
testParam4=This is test param 4