标签:gradle android android-s tutorials
写在前面的话:
博主最近在学习Android Studio相关的东西。Gradle相对于我这个从Eclipse转过来的Android开发者,也算是一个全新的事物。但它却承担着Android构建系统中相当重要的一环。本着与人方便,自己方便的精神,觉得有必要翻译一下《Gradle User Guide》中的Tutorials相关部分。由于英语水平相当有限,请大家多多指教。
文章地址:http://blog.csdn.net/mikulee/article/details/45478177
英文原文地址:http://gradle.org/docs/current/userguide/tutorial_using_tasks.html
请尊重相关知识版权,谢谢。
Gradle中的所有东西都以这两个概念为基础:projects 和 tasks.
每个Gradle构建都以一个或多个projects组合而成。一个project代表的意义依赖于你正在用Gradle处理什么。例如,一个project可能代表一个库(JAR)或网页应用(web application).它可能代表其他项目的库的ZIP压缩包发布版。一个project并不需要代表要构建的什么确切东西,它可能仅仅用来说明某个东西已经完成了,例如发布你的应用到工作或者生产环节去。如果你对这些概念性的东西还不够清楚,请不要紧张。Gradle的构建规则支持添加一个或多个project到底是什么的具体定义。
每个project都是有一个或多个tasks组成。一个task代表一个不可分割的构建工作。它可能编译一些calsses,创建JAR,生成Javadoc,或者发布一些文件到仓库里。
从现在开始,我们将把注意力集中在为一个project构建定义一些简单的tasks.后面的章节会深入学习处理多个projects的projects和tasks。
当你用gradle命令运行一个Gradle构建的时候,gradle命令会在当前目录查找一个命名为build.gradle的文件。我们称呼build.gradle文件为构建脚本(build script),虽然严格来说,它是一个构建配置脚本。这个构建脚本定义了一个project及一些和它相关的的tasks.
为了验证这个,创建一个build.gradle文件,并添加下面的构建脚本。
例子 6.1. 你的第一个构建脚本
build.gradle
task hello {
doLast {
println ‘Hello world!‘
}
}
在命令行shell中,进入到包含这个build.gradle的目录,运行gradle -q hello去执行这个构建脚本。
例子 6.2. 运行一个构建脚本
gradle -q hello的输出
> gradle -q hello
Hello world!
这里发生了什么?这个构建脚本定义了一个单独的命名为hello的任务,并添加了一个动作进去。当你运行gradle hello的时候,Gradle执行了这个hello任务,继而执行了你提供的动作。这个动作是一个包含一些执行Groovy代码的闭包。
如果你觉得这个看起来像Ant target,你是对的。Gradle task任务和Ant target是差不多的,但你会看到,它们(Gradle)更强大.我们使用了一个和Ant不一样的专业术语,因为我们觉得task这个词比target更加传神。不幸的是,这是一个和ant冲突的术语,例如Ant中调用自己的命令,例如javac或copy,tasks。所以当我们提到tasks时,我们要说的是Gradle tasks.如果我们要说 Ant tasks(Ant 命令)时,我们会明确的说 Ant task。
这里有一个快速定义一个task的方法,非常简洁,例如要定义上面提到的hell task。
例子6.3.一个task定义快捷方式
build.gradle
task hell << {
println ‘Hello world!‘
}
同样,我们定义了一个名称为hello的可执行任务,其中包含了一个单独的闭包。我们将会在整个用户指南中使用这种风格的task定义方式。
Gradle构建脚本给予你一个全功能的Groovy。作为引子,请看下面这2个示例:
例子6.4. 在Gradle任务中使用Groovy
build.gradle
task upper << {
String someString = ‘mY_nAmE‘
println "Original: " + someString
println "Upper case: " + someString.toUpperCase()
}
gradle -q upper 输出:
> gradle -q upper
Original: mY_nAmE
Upper case: MY_NAME
或
例子6.5. 在Gradle任务中使用Groovy
build.gradle
task count << {
4.times { print "$it " }
}
gradle -q count 输出:
> gradle -q count
0 1 2 3
你很可能已经想到,你可以声明一些可以依赖于其他任务的任务。
例子6.6. 声明一个依赖于其他task的task
build.gradle
task hello << {
println ‘Hello world!‘
}
task intro(dependsOn: hello) << {
println "I‘m Gradle"
}
gradle -q intro 输出:
> gradle -q intro
Hello world!
I‘m Gradle
可以添加一个还没存在的task作为依赖:
例子6.7. 懒依赖-另外的task还没存在
build.gradle
task taskX(dependsOn: ‘taskY‘) << {
println ‘taskX‘
}
task taskY << {
println ‘taskY‘
}
gradle -q taskX 输出:
> gradle -q taskX
taskY
taskX
taskX对应taskY的依赖关系先于taskY的定义。这对应多重项目构建非常重要。更多任务依赖的讨论可以参考 为一个task添加多个依赖。
请注意,当你要关联一个未存在的task时,不可以使用快捷标记。(参看6.8小节)
Groovy的能力远远大于定义一个单独的task.例如,你可以使用它来动态创建task。
例子6.8. 动态创建task
build.gradle
4.times { counter ->
task "task$counter" << {
println "I‘m task number $counter"
}
}
gradle -q task1 输出:
> gradle -q task1
I‘m task number 1
一旦任务被创建,任务就可以被API访问到。例如,你可以使用这个在运行时去动态给一个任务添加依赖。Ant是不允许这种行为的。
例子6.9. 通过API访问一个任务-添加一个依赖
build.gradle
4.times { counter ->
task "task$counter" << {
println "I‘m task number $counter"
}
}
task0.dependsOn task2, task3
gradle -q task0 输出:
> gradle -q task0
I‘m task number 2
I‘m task number 3
I‘m task number 0
或者你可以为当前已经存在的任务添加其他行为。
例子6.10. 通过API访问一个任务-添加行为
build.gradle
task hello << {
println ‘Hello Earth‘
}
hello.doFirst {
println ‘Hello Venus‘
}
hello.doLast {
println ‘Hello Mars‘
}
hello << {
println ‘Hello Jupiter‘
}
gradle -q task0 输出:
> gradle -q hello
Hello Venus
Hello Earth
Hello Mars
Hello Jupiter
对doFirst和doLast的调用可以执行多次。他们添加一个动作到任务动作列表的开始或结束位置。当任务被执行时,在动作动作列表中的动作会被按顺序的执行。操作符<<是doLast的同名词。
在上一个例子中,你可能早已注意到有一个方便的标记符号去访问一个已经存在的task。作为构建脚本的一个属性,在每个task中都可以使用这种快捷方式。
例子6.11. 用构建脚本属性的方式访问task
build.gradle
task hello << {
println ‘Hello world!‘
}
hello.doLast {
println "Greetings from the $hello.name task."
}
gradle -q hello 输出:
> gradle -q hello
Hello world!
Greetings from the hello task.
这功能使构建脚本代码可读性更加强,特别是当使用插件提供的任务时,就像一个编译任务。
你可以向任务添加自定义属性。添加一个名称为myProperty的属性,并设置 ext.myProperty一个初始值。从此以后,这个属性就可以像预先定义的task属性一样被读取。
例子6.12. 向任务添加一个扩展属性
build.gradle
task myTask {
ext.myProperty = "myValue"
}
task printTaskProperties << {
println myTask.myProperty
}
gradle -q printTaskProperties 输出:
> gradle -q printTaskProperties
myValue
扩展属性并不仅限于task.你可以获取更多扩展属性的相关内容,请参考扩展属性。
Ant tasks在Gradle中是非常优秀的。Gradle中可以非常简单的使用Groovy来为Ant task提供非常优秀集成。Groovy封装了抽象的AntBuilder。在Gradle中使用Ant task相当方便,而且比在build.xml中使用Ant tasks更加强大有力。例如下面的示例,你可以学到怎么执行Ant tasks和怎么访问Ant属性。
例子6.13. 使用AntBuilder去执行ant.loadfile target
build.gradle
task loadfile << {
def files = file(‘../antLoadfileResources‘).listFiles().sort()
files.each { File file ->
if (file.isFile()) {
ant.loadfile(srcFile: file, property: file.name)
println " *** $file.name ***"
println "${ant.properties[file.name]}"
}
}
}
gradle -q loadfile 输出:
> gradle -q loadfile
*** agile.manifesto.txt ***
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
*** gradle.manifesto.txt ***
Make the impossible possible, make the possible easy and make the easy elegant.
(inspired by Moshe Feldenkrais)
你可以在你的构建脚本中使用Ant去做更多事情。你可以参考在Gradle中使用Ant。
Gradle为你如何组织你的构建逻辑划分等级。组织构建逻辑的第一级便是上面的例子,提前一个方法。
例子6.14. 使用方法去组织你的构建逻辑
build.gradle
task checksum << {
fileList(‘../antLoadfileResources‘).each {File file ->
ant.checksum(file: file, property: "cs_$file.name")
println "$file.name Checksum: ${ant.properties["cs_$file.name"]}"
}
}
task loadfile << {
fileList(‘../antLoadfileResources‘).each {File file ->
ant.loadfile(srcFile: file, property: file.name)
println "I‘m fond of $file.name"
}
}
File[] fileList(String dir) {
file(dir).listFiles({file -> file.isFile() } as FileFilter).sort()
}
gradle -q loadfile 输出:
> gradle -q loadfile
I‘m fond of agile.manifesto.txt
I‘m fond of gradle.manifesto.txt
迟点你将会看到在多重项目构建方面,子项目之间可以有很多共享的方法。如果你的构建逻辑变得更加复杂,Gradle可以提供给你其他非常方便的方法去组织构建逻辑。我们已经准备了整整一个章节去讨论它。可以参看组织构建逻辑。
Gradle允许你为你的构建定义一个或多个默认tasks。
例子6.15. 定义默认任务
build.gradle
defaultTasks ‘clean‘, ‘run‘
task clean << {
println ‘Default Cleaning!‘
}
task run << {
println ‘Default Running!‘
}
task other << {
println "I‘m not a default task!"
}
gradle -q 输出:
> gradle -q
Default Cleaning!
Default Running!
这个等价于去允许gradle clean run。在多重项目构建中,每个子项目可以有自己指定的默认tasks.如果一个子项目没有指定默认task,父项目的默认task会被使用(假如父项目存在默认task)。
就如我们迟点详细说明的(参考构建的生命周期),Gradle有一个配置阶段和一个执行阶段。配置阶段完成后,Gradle了解到所有将会被执行到的tasks.Gradle会给你提供一个钩子,让你可以使用到这些信息。一个用例是去检查release task是否在这些即将被执行的任务之中。根据这个,你可以给一些变量赋予不同的值。
在下面这个例子中,distribution和release这2个tasks会有不同的版本值。
例子6.16. 选择不同的task,输出不同的结果
build.gradle
task distribution << {
println "We build the zip with version=$version"
}
task release(dependsOn: ‘distribution‘) << {
println ‘We release now‘
}
gradle.taskGraph.whenReady {taskGraph ->
if (taskGraph.hasTask(release)) {
version = ‘1.0‘
} else {
version = ‘1.0-SNAPSHOT‘
}
}
gradle -q distribution 输出:
> gradle -q distribution
We build the zip with version=1.0-SNAPSHOT
gradle -q release 输出:
> gradle -q release
We build the zip with version=1.0
We release now
重要的事情是whenReady在release被执行前影响到了release task。即使release不是主task,也可以生效。
在这个章节,我们简单的介绍了task。但对task的学习还没结束。如果你想更详细的学习task,请到这里学习:更多关于task的事情。
否则,继续第七章Java快速开始的教程和第八章依赖管理基础。
标签:gradle android android-s tutorials
原文地址:http://blog.csdn.net/mikulee/article/details/45478177