除创建任务之外,Gradle构建文件的重要功能就是定义属性,Gradle允许为Project和 Task已有的属性指定属性值,也可为Project和 Task添加属性。
创建一个新的gradle项目

为已有属性指定属性值
Project、Task都是 Gradle提供的API,它们本身具有内置属性,因此可以在构建文件中为这些属性指定属性值。
// 为Project内置属性指定属性值
version = 1.0
description = 'Project的属性'
//定义showProps任务,显示Project和Task内置属性
task showProps{
//为Task内置属性指定属性值
description = 'Task的属性'
doLast {
println version
//输出Task属性
println description
//由于Task和Project都有description属性,
//因此下面要显示指定访问project的description属性
println project.description
}
}

Project 常用的属性有如下几个,这些属性大部分都可通过上面方式来指定属性值。
通过ext添加属性
如果需要为Project 和 Task添加属性,则可通过它们各自的ext进行添加。由于Project和 Task都实现了ExtensionAware接口,因此它们都可通过ext来添加属性。
Gradle中所有实现了ExtensionAware接口的API都可通过ext来添加属性。
ext.prop1 = '添加的项目属性一'
ext.prop2 = '添加的项目属性二'
//使用ext方法,传入代码块来设置属性
ext {
prop3 = '添加的项目属性三'
prop4 = '添加的项目属性四'
}
task showAddedProps {
ext.prop1 = '添加的任务属性一'
ext.prop2 = '添加的任务属性二'
//使用ext方法,传入代码块来设置属性
ext {
prop3 = '添加的任务属性三'
prop4 = '添加的任务属性四'
}
doLast {
println prop1
println project.prop1
println prop2
println project.prop2
println prop3
println project.prop3
println prop4
println project.prop4
}
}
上面4行粗体字代码不在任何Task之内,这就是为项目添加属性。如果将上面4行粗体字代码放在Task 的初始化代码块内,那么就意味着为该Task定义属性,如上面showAddedProps任务中的初始化代码所示。
运行

通过-P选项添加属性
Gradle还允许在运行 gradle命令时通过-P选项来添加属性,使用这种方式添加的属性都是项目属性。
task showCmdProp {
doLast {
println("系统显卡类型:${graphics}")
println("系统显卡类型:${project.graphics}")
}
}
运行

通过JVM参数添加属性
Gradle也允许在运行 gradle命令时通过JVM参数来添加属性,Java允许通过-D选项为JVM设置参数,使用这种方式添加的属性也都是项目属性。
task showJVMProp {
doLast {
println ("添加的JVM属性:${p1}")
}
}

如果任务的执行和前一次执行比较没有造成任何改变,Gradle不会重复执行该任务,这样就可以提高Gradle的构建效率。
那么Gradle如何判断任务的执行是否造成改变呢? Gradle将每个任务都当成一个黑盒子:只要该任务的输入部分没有改变,输出部分也没有改变——Gradle就会判断该任务的执行没有造成任何改变。
Gradle的Task使用 inputs属性来代表任务的输入,该属性是一个 TaskInputs类型的对象;Task使用outputs属性来代表任务的输出,该属性是一个TaskOutputs类型的对象。
不管是TaskInputs,还是TaskOuputs,它们都支持设置文件、文件集、目录、属性等,只要它们没有发生改变,Gradle就认为该任务的输入、输出没有发生改变。
创建新gradle项目

构建文件
//定义fileContentCopy任务
task fileContenCopy {
//定义代表source目录的文件集
def sourceTxt = fileTree("source")
def dest = file('dist.txt')
//定义该任务的输入、输出
inputs.dir sourceTxt
outputs.file dest
doLast {
//调用File对象的withPrintWriter方法
dest.withPrintWriter {
writer ->
sourceTxt.each{
s -> writer.write(s.text)
}
}
}
}

运行


再次执行该命令

从上面的输出结果可以看出,第二次执行该命令时不再真正执行该任务,程序只是将该任务更新到最新(up-to-date)。