本文來源於:http://blog.csdn.net/maosidiaoxian/article/details/45664943
projects 和 tasks是Gradle中最重要的兩個概念
Everything in Gradle sits on top of two basic concepts: projects and tasks.
任何一個Gradle構建都是由一個或多個 projects 組成.每個project包括許多可構建組成部分.
這完全取決於你要構建些什麼.舉個栗子.每個project或許是一個jar包或者一個web應用, 它也可以是一個由許多其他項目中產生的jar構成的zip壓縮包.一個project不必描述它只能進行構建操作. 它也可以部署你的應用或搭建你的環境.不要擔心它像聽上去的那樣龐大. Gradle的build-by-convention可以讓您來具體定義一個project到底該做什麼.
Every Gradle build is made up of one or more projects.
What a project represents depends on what it is that you are doing with Gradle. For example, a project might represent a library JAR or a web application. It might represent a distribution ZIP assembled from the JARs produced by other projects. A project does
not necessarily represent a thing to be built. It might represent a thing to be done, such as deploying your application to staging or production environments. Don't worry if this seems a little vague for now. Gradle's build-by-convention support adds a more
concrete definition for what a project is.
每個project都由多個tasks組成.每個task都代表了構建執行過程中的一個原子性操作.如編譯,打包,生成javadoc,發佈到某個倉庫等操作
Each project is made up of one or more tasks.
A task represents some atomic piece of work which a build performs. This might be compiling some classes, creating a JAR, generating javadoc, or publishing some archives to a repository.
到目前爲止,可以發現我們可以在一個project中定義一些簡單任務,後續章節將會闡述多項目構建和多項目多任務的內容.
For now, we will look at defining some simple tasks in a build with one project. Later chapters will look at working with multiple projects and more about working with projects and tasks.
你可以通過在命令行運行gradle命令來執行構建, gradle命令會從當前目錄下尋找 build.gradle
文件來執行構建.我們稱 build.gradle
文件爲構建腳本.
嚴格來說這其實是一個構建配置腳本,後面你會瞭解到這個構建腳本定義了一個project和一些默認的task
You run a Gradle build using the gradle command.
The gradle command
looks for a file called build.gradle
in
the current directory. [2] We
call this build.gradle
file
a build script, although
strictly speaking it is a build configuration script, as we will see later. The build script defines a project and its tasks.
你可以創建如下腳本到 build.gradle
中
To try this out, create the following build script named build.gradle
.
例6.1. 第一個構建腳本
Example 6.1. The first build script
build.gradle
task hello {
doLast {
println 'Hello world!'
}
}
然後在該文件所在目錄執行 gradle -q hello
In a command-line shell, enter into the containing directory and execute the build script by running gradle
-q hello
:
-q
參數的作用是什麼?
What does -q
do?
該文檔的示例中很多地方在調用gradle命令時都加了 -q
參數.
該參數用來控制gradle的日誌級別,可以保證只輸出我們需要的內容. 具體可參閱本文檔 第十八章 日誌 來了解更多參數和信息.
Most of the examples in this user guide are run with the -q
command-line
option. This suppresses Gradle's log messages, so that only the output of the tasks is shown. This keeps the example output in this user guide a little clearer. You don't need to use this option if you don't want. See Chapter 18, Logging for
more details about the command-line options which affect Gradle's output.
例6.2. 執行腳本
Example 6.2. Execution of a build script
Output of gradle
-q hello
> gradle -q hello Hello world!
上面的腳本定義了一個叫做 hello
的
task,並且給它添加了一個動作. 當執行gradle
hello
的時候, Gralde便會去調用 hello
這個任務來執行給定操作.這些操作其實就是一個用groovy書寫的閉包
What's going on here? This build script defines a single task, called hello
,
and adds an action to it. When you run gradle
hello
, Gradle executes the hello
task,
which in turn executes the action you've provided. The action is simply a closure containing some Groovy code to execute.
如果你覺得它看上去跟Ant中的targets很像,那麼是對的. Gradle的tasks就相當於Ant中的targets.不過你會發現他功能更加強大. 我們只是換了一個比target更形象的另外一個術語.不幸的是這恰巧與Ant中的術語有些衝突. ant 命令中有諸如javac、copy、tasks.所以當該文檔中提及tasks時,除非特別指明 ant
task. 否則指的均是指Gradle中的tasks.
If you think this looks similar to Ant's targets, well, you are right. Gradle tasks are the equivalent to Ant targets. But as you will see, they are much more powerful. We have used a different terminology than Ant as we think the word task is
more expressive than the word target.
Unfortunately this introduces a terminology clash with Ant, as Ant calls its commands, such as javac
or copy
,
tasks. So when we talk about tasks, we alwaysmean
Gradle tasks, which are the equivalent to Ant's targets. If we talk about Ant tasks (Ant commands), we explicitly say ant
task.
用一種更簡潔的方式來定義 上面的 hello
任務.
There is a shorthand way to define a task like our hello
task
above, which is more concise.
例6.3.快速定義任務
Example 6.3. A task definition shortcut
build.gradle
task hello << {
println 'Hello world!'
}
上面的腳本又一次採用閉包的方式來定義了一個叫做hello的任務,本文檔後續章節中我們將會更多的採用這種風格來定義任務.
Again, this defines a task called hello
with
a single closure to execute. We will use this task definition style throughout the user guide.
Gradle腳本採用Groovy書寫,作爲開胃菜,看下下面這個栗子. Gradle's build scripts expose to you the full power of Groovy. As an appetizer, have a look at this:
•例6.4 在gradle任務中採用groovy
Example 6.4. Using Groovy in Gradle's tasks
build.gradle
task upper << { String someString = 'mY_nAmE' println "Original: " + someString println "Upper case: " + someString.toUpperCase() }
Output of gradle
-q upper
> gradle -q upper Original: mY_nAmE Upper case: MY_NAME
或者
or
你可以按如下方式創建任務間的依賴關係
As you probably have guessed, you can declare dependencies between your tasks.
在兩個任務之間指明依賴關係
Example 6.6. Declaration of dependencies between tasks
build.gradle
task hello << { println 'Hello world!' } task intro(dependsOn: hello) << { println "I'm Gradle" }
gradle
-q intro
的輸出結果
Output of gradle
-q intro
> gradle -q intro Hello world! I'm Gradle
添加依賴task也可以不必首先聲明被依賴的task.
To add a dependency, the corresponding task does not need to exist.
Example 6.7. 延遲依賴 .Lazy dependsOn - the other task does not exist (yet)
build.gradle
task taskX(dependsOn: 'taskY') << { println 'taskX' } task taskY << { println 'taskY' }
Output of gradle
-q taskX
> gradle -q taskX taskY taskX
可以看到, taskX
是
在 taskY
之前定義的,這在多項目構建中非常有用
關於任務依賴的更多信息可以查看章節 15.4,
“給任務添加依賴”..
The dependency of taskX
to taskY
is
declared before taskY
is
defined. This is very important for multi-project builds. Task dependencies are discussed in more detail in Section 15.4,
“Adding dependencies to a task”.
注意:當引用的任務尚未定義的時候不可使用短標記法(see 章節 6.8,
“短標記法”) 來運行任務.
Please notice that you can't use shortcut notation (see Section 6.8,
“Shortcut notations”) when referring to a task that is not yet defined.
藉助Groovy的強大不僅可以定義簡單任務還能做更多的事.例如,可以動態定義任務.
The power of Groovy can be used for more than defining what a task does. For example, you can also use it to dynamically create tasks.
一旦任務被創建後,任務之間可以通過API進行相互訪問.這也是與Ant的不同之處.比如可以增加一些依賴.
Once tasks are created they can be accessed via an API.
This is different to Ant. For example you can create additional dependencies.
例 6.9. 通過API進行任務之間的通信 - 增加依賴
Example 6.9. Accessing a task via API - adding a dependency
build.gradle
4.times { counter -> task "task$counter" << { println "I'm task number $counter" } } task0.dependsOn task2, task3
gradle
-q task0
的輸出結果.
Output of gradle
-q task0
> gradle -q task0 I'm task number 2 I'm task number 3 I'm task number 0
爲已存在的任務增加行爲.
Or you can add behavior to an existing task.
例 6.10. 通過API進行任務之間的通信 - 增加任務行爲
Example 6.10. Accessing a task via API - adding behaviour
build.gradle
task hello << { println 'Hello Earth' } hello.doFirst { println 'Hello Venus' } hello.doLast { println 'Hello Mars' } hello << { println 'Hello Jupiter' }
Output of gradle
-q hello
> gradle -q hello Hello Venus Hello Earth Hello Mars Hello Jupiter
doFirst
和 doLast
可以進行多次調用.
他們分別被添加在任務的開頭和結尾.當任務開始執行時這些動作會按照既定順序進行.其中 <<
操作符
是 doLast
的簡寫方式.
The calls doFirst
and doLast
can
be executed multiple times. They add an action to the beginning or the end of the task's actions list. When the task executes, the actions in the action list are executed in order. The <<
operator
is simply an alias for doLast
.
你早就注意到了吧,沒錯,每個任務都是一個腳本的屬性,你可以訪問它:
As you might have noticed in the previous examples, there is a convenient notation for accessing an existing task.
Each task is available as a property of the build script:
例 6.11. 以屬性的方式訪問任務
Example 6.11. Accessing task as a property of the build script
build.gradle
task hello << { println 'Hello world!' } hello.doLast { println "Greetings from the $hello.name task." }
gradle
-q hello
的輸出結果
Output of gradle
-q hello
> gradle -q hello Hello world! Greetings from the hello task.
對於插件提供的內置任務。這尤其方便(例如:complie)
This enables very readable code, especially when using the out of the box tasks provided by the plugins (e.g. compile
).
你可以爲一個任務添加額外的屬性.例如,新增一個叫做 myProperty
的屬性,用 ext.myProperty
的方式給他一個初始值.這樣便增加了一個自定義屬性.
You can add your own properties to a task. To add a property named myProperty
,
set ext.myProperty
to
an initial value. From that point on, the property can be read and set like a predefined task property.
例 6.12. 爲任務增加自定義屬性
Example 6.12. Adding extra properties to a task
build.gradle
task myTask {
ext.myProperty = "myValue"
}
task printTaskProperties << {
println myTask.myProperty
}
gradle
-q printTaskProperties
的輸出結果
Output of gradle
-q printTaskProperties
> gradle -q printTaskProperties myValue
Extra properties aren't limited to tasks. You can read more about them in Section 13.4.2, “Extra properties”.
Ant任務是Gradle中的一等公民.Gradle藉助Groovy對Ant任務進行了優秀的整合. Gradle自帶了一個AntBuilder
,在Gradle中調用Ant任務比在 build.xml
中調用更加的方便和強大.
通過下面的例子你可以學到如何調用一個Ant任務以及如何與Ant中的屬性進行通信.
Ant tasks are first-class citizens in Gradle. Gradle provides excellent integration for Ant tasks by simply relying on Groovy. Groovy is shipped with the fantastic AntBuilder
.
Using Ant tasks from Gradle is as convenient and more powerful than using Ant tasks from a build.xml
file.
From the example below, you can learn how to execute ant tasks and how to access ant properties:
例 6.13. 利用AntBuilder執行 ant.loadfile
Example 6.13. Using AntBuilder to execute 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
的輸出結果
Output of 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做更多的事情.想了解更多請參閱 章節 17, 在Gradle中調用Ant
There is lots more you can do with Ant in your build scripts. You can find out more in Chapter 17, Using
Ant from Gradle .
Gradle的強大要看你如何編寫腳本邏輯.針對上面的例子,首先要做的就是要抽取方法.
Gradle scales in how you can organize your build logic. The first level of organizing your build logic for the example above, is extracting a method.
例 6.14 利用方法組織腳本邏輯
Example 6.14. Using methods to organize your build logic
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
的輸出結果
Output of gradle
-q loadfile
> gradle -q loadfile I'm fond of agile.manifesto.txt I'm fond of gradle.manifesto.txt
在後面的章節你會看到類似出去出來的方法可以在多項目構建中的子項目中調用. 無論構建邏輯多複雜,Gradle都可以提供給你一種簡便的方式來組織它們.想了解更多請參閱 章節 59, 組織構建邏輯.
Later you will see that such methods can be shared among subprojects in multi-project builds. If your build logic becomes more complex, Gradle offers you other very convenient ways to organize it. We have devoted a whole chapter to this. See Chapter 59, Organizing
Build Logic.
Gradle允許在腳本中定義多個默認任務.
Gradle allows you to define one or more default tasks for your build.
例 6.15. 定義默認任務
Example 6.15. Defining a default tasks
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
的輸出結果.
Output of gradle
-q
> gradle -q Default Cleaning! Default Running!
這與直接調用gradle
clean run
效果是一樣的. 在多項目構建中,每個子項目都可以指定單獨的默認任務.如果子項目未進行指定將會調用父項目指定的的默認任務.
This is equivalent to running gradle
clean run
. In a multi-project build every subproject can have its own specific default tasks. If a subproject does not specify default tasks, the default tasks of the parent project are used (if defined).
稍後會對Gradle的配置階段和運行階段進行詳細說明 (詳見 章節 55, 構建的生命週期 )配置階段後,Gradle會了解所有要執行的任務
Gradle提供了一個鉤子來捕獲這些信息.一個例子就是可以檢查已經執行的任務中有沒有被釋放.藉由此,你可以爲一些變量賦予不同的值.
As we later describe in full detail (see Chapter 55, The
Build Lifecycle), Gradle has a configuration phase and an execution phase. After the configuration phase, Gradle knows all tasks that should be executed. Gradle offers you a hook to make use of this information. A use-case for this would be to check
if the release task is among the tasks to be executed. Depending on this, you can assign different values to some variables.
在下面的例子中,爲distribution
和release
任務賦予了不同的 version
值.
In the following example, execution of the distribution
and release
tasks
results in different value of the version
variable.
例 6.16. 依賴任務的不同輸出
Example 6.16. Different outcomes of build depending on chosen tasks
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
的輸出結果
Output of gradle
-q distribution
> gradle -q distribution We build the zip with version=1.0-SNAPSHOT
gradle
-q release
的輸出結果
Output of gradle
-q release
> gradle -q release We build the zip with version=1.0 We release now
whenReady
會在已發佈的任務之前影響到已發佈任務的執行.
即使已發佈的任務不是 主要任務(也就是說,即使這個任務不是通過命令行直接調用)
The important thing is that whenReady
affects
the release task before the
release task is executed. This works even when the release task is not the primary task
(i.e., the task passed to the gradle command).
在本章中,我們瞭解了什麼是task,但這還不夠詳細.欲知更多請參閱 章節 15, 任務進階
In this chapter, we have had a first look at tasks. But this is not the end of the story for tasks. If you want to jump into more of the details, have a look at Chapter 15, More
about Tasks .
另外,可以目錄繼續學習 第七章 , Java
快速入門 和 第八章 , 依賴管理基礎.
Otherwise, continue on to the tutorials in Chapter 7, Java
Quickstart and Chapter 8, Dependency
Management Basics.