在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ 物聯(lián)網(wǎng)/ 任務(wù)詳述
問題反饋
Gradle 插件
Scala 插件
Gradle 命令行的基本使用
任務(wù)詳述
安裝
概述
教程-雜七雜八
構(gòu)建環(huán)境
依賴管理基礎(chǔ)
使用 Gradle 圖形用戶界面
使用文件
CodeNarc 插件
Sonar 插件
Groovy 插件
Sonar Runner 插件
OSGi 插件
Ear 插件
Gradle 守護(hù)進(jìn)程
Java 插件
簡介
構(gòu)建基礎(chǔ)
FindBugs 插件
Groovy 快速入門
JaCoCo 插件
PMD 插件
War 插件
Checkstyle 插件
日志
Java 構(gòu)建入門
Jetty 插件
從 Gradle 中調(diào)用 Ant
標(biāo)準(zhǔn)的 Gradle 插件
Web 工程構(gòu)建
JDepend 插件
編寫構(gòu)建腳本

任務(wù)詳述

在入門教程構(gòu)建基礎(chǔ)中,你已經(jīng)學(xué)習(xí)了如何創(chuàng)建簡單的任務(wù)。之后您還學(xué)習(xí)了如何將其他行為添加到這些任務(wù)中。并且你已經(jīng)學(xué)會了如何創(chuàng)建任務(wù)之間的依賴。這都是簡單的任務(wù)。但 Gradle 讓任務(wù)的概念更深遠(yuǎn)。Gradle 支持增強的任務(wù),也就是,有自己的屬性和方法的任務(wù)。這是真正的與你所使用的 Ant 目標(biāo)(target)的不同之處。這種增強的任務(wù)可以由你提供,或由 Gradle 提供。

定義任務(wù)

在構(gòu)建基礎(chǔ)中我們已經(jīng)看到如何通過關(guān)鍵字這種風(fēng)格來定義任務(wù)。在某些情況中,你可能需要使用這種關(guān)鍵字風(fēng)格的幾種不同的變式。例如,在表達(dá)式中不能用這種關(guān)鍵字風(fēng)格。

定義任務(wù)

build.gradle

task(hello) << {
    println "hello"
}
task(copy, type: Copy) {
    from(file('srcDir'))
    into(buildDir)
}  

您還可以使用字符串作為任務(wù)名稱:

定義任務(wù) — — 使用字符串作為任務(wù)名稱

build.gradle

task('hello') <<
{
    println "hello"
}
task('copy', type: Copy) {
    from(file('srcDir'))
    into(buildDir)
}  

對于定義任務(wù),有一種替代的語法你可能更愿意使用:

使用替代語法定義任務(wù)

build.gradle

tasks.create(name: 'hello') << {
    println "hello"
}
tasks.create(name: 'copy', type: Copy) {
    from(file('srcDir'))
    into(buildDir)
}  

在這里我們將任務(wù)添加到 tasks 集合。關(guān)于 create() 方法的更多變化可以看看 TaskContainer。

定位任務(wù)

你經(jīng)常需要在構(gòu)建文件中查找你所定義的任務(wù),例如,為了去配置或是依賴它們。對這樣的情況,有很多種方法。首先,每個任務(wù)都可作為項目的一個屬性,并且使用任務(wù)名稱作為這個屬性名稱:

以屬性方式訪問任務(wù)

build.gradle

task hello
println hello.name
println project.hello.name  

任務(wù)也可以通過 tasks 集合來訪問。

通過 tasks 集合訪問任務(wù)

build.gradle

task hello
println tasks.hello.name
println tasks['hello'].name  

您可以從任何項目中,使用 tasks.getByPath() 方法獲取任務(wù)路徑并且通過這個路徑來訪問任務(wù)。你可以用任務(wù)名稱,相對路徑或者是絕對路徑作為參數(shù)調(diào)用 getByPath() 方法。

通過路徑訪問任務(wù)

build.gradle

project(':projectA') {
    task hello
}
task hello
println tasks.getByPath('hello').path
println tasks.getByPath(':hello').path
println tasks.getByPath('projectA:hello').path
println tasks.getByPath(':projectA:hello').path  

gradle -q hello的輸出結(jié)果

> gradle -q hello
:hello
:hello
:projectA:hello
:projectA:hello  

有關(guān)查找任務(wù)的更多選項,可以看一下 TaskContainer。

配置任務(wù)

作為一個例子,讓我們看看由 Gradle 提供的 Copy 任務(wù)。若要創(chuàng)建 Copy 任務(wù),您可以在構(gòu)建腳本中聲明:

創(chuàng)建一個復(fù)制任務(wù)

build.gradle

task myCopy(type: Copy)  

上面的代碼創(chuàng)建了一個什么都沒做的復(fù)制任務(wù)??梢允褂盟?API 來配置這個任務(wù)(見 Copy)。下面的示例演示了幾種不同的方式來實現(xiàn)相同的配置。

配置任務(wù)的幾種方式

build.gradle

Copy myCopy = task(myCopy, type: Copy)
myCopy.from 'resources'
myCopy.into 'target'
myCopy.include('**/*.txt', '**/*.xml', '**/*.properties')  

這類似于我們通常在 Java 中配置對象的方式。您必須在每一次的配置語句重復(fù)上下文 (myCopy)。這顯得很冗余并且很不好讀。

還有另一種配置任務(wù)的方式。它也保留了上下文,且可以說是可讀性最強的。它是我們通常最喜歡的方式。

配置任務(wù)-使用閉包

build.gradle

task myCopy(type: Copy)
myCopy {
   from 'resources'
   into 'target'
   include('**/*.txt', '**/*.xml', '**/*.properties')
}  

這種方式適用于任何任務(wù)。該例子的第 3 行只是 tasks.getByName() 方法的簡潔寫法。特別要注意的是,如果您向 getByName() 方法傳入一個閉包,這個閉包的應(yīng)用是在配置這個任務(wù)的時候,而不是任務(wù)執(zhí)行的時候。

您也可以在定義一個任務(wù)的時候使用一個配置閉包。

使用閉包定義任務(wù)

build.gradle

task copy(type: Copy) {
   from 'resources'
   into 'target'
   include('**/*.txt', '**/*.xml', '**/*.properties')
}  

對任務(wù)添加依賴

定義任務(wù)的依賴關(guān)系有幾種方法。在任務(wù)依賴中,已經(jīng)向你介紹了使用任務(wù)名稱來定義依賴。任務(wù)的名稱可以指向同一個項目中的任務(wù),或者其他項目中的任務(wù)。要引用另一個項目中的任務(wù),你需要把它所屬的項目的路徑作為前綴加到它的名字中。下面是一個示例,添加了從 projectA:taskX 到 projectB:taskY 的依賴關(guān)系:

從另一個項目的任務(wù)上添加依賴

build.gradle

project('projectA') {
    task taskX(dependsOn: ':projectB:taskY') << {
        println 'taskX'
    }
}
project('projectB') {
    task taskY << {
        println 'taskY'
    }
}  

gradle -q taskX 的輸出結(jié)果

> gradle -q taskX
taskY
taskX  

您可以使用一個 Task 對象而不是任務(wù)名稱來定義依賴,如下:

使用 task 對象添加依賴

build.gradle

task taskX << {
    println 'taskX'
}
task taskY << {
    println 'taskY'
}
taskX.dependsOn taskY  

gradle -q taskX的輸出結(jié)果

> gradle -q taskX
taskY
taskX  

對于更高級的用法,您可以使用閉包來定義任務(wù)依賴。在計算依賴時,閉包會被傳入正在計算依賴的任務(wù)。這個閉包應(yīng)該返回一個 Task 對象或是 Task 對象的集合,返回值會被作為這個任務(wù)的依賴項。下面的示例是從 taskX 加入了項目中所有名稱以 lib 開頭的任務(wù)的依賴:

使用閉包添加依賴

build.gradle

task taskX << {
    println 'taskX'
}
taskX.dependsOn {
    tasks.findAll { task -> task.name.startsWith('lib') }
}
task lib1 << {
    println 'lib1'
}
task lib2 << {
    println 'lib2'
}
task notALib << {
    println 'notALib'
}  

gradle -q taskX 的輸出結(jié)果

> gradle -q taskX
lib1
lib2
taskX  

有關(guān)任務(wù)依賴的詳細(xì)信息,請參閱 Task 的 API。

任務(wù)排序

任務(wù)排序還是一個孵化中的功能。請注意此功能在以后的 Gradle 版本中可能會改變。

在某些情況下,控制兩個任務(wù)的執(zhí)行的順序,而不引入這些任務(wù)之間的顯式依賴,是很有用的。任務(wù)排序和任務(wù)依賴之間的主要區(qū)別是,排序規(guī)則不會影響那些任務(wù)的執(zhí)行,而僅將執(zhí)行的順序。

任務(wù)排序在許多情況下可能很有用:

  • 強制任務(wù)順序執(zhí)行: 如,'build' 永遠(yuǎn)不會在 'clean' 前面執(zhí)行。
  • 在構(gòu)建中盡早進(jìn)行構(gòu)建驗證:如,驗證在開始發(fā)布的工作前有一個正確的證書。
  • 通過在長久驗證前運行快速驗證以得到更快的反饋:如,單元測試應(yīng)在集成測試之前運行。
  • 一個任務(wù)聚合了某一特定類型的所有任務(wù)的結(jié)果:如,測試報告任務(wù)結(jié)合了所有執(zhí)行的測試任務(wù)的輸出。

有兩種排序規(guī)則是可用的:"必須在之后運行"和"應(yīng)該在之后運行"。

通過使用 “ 必須在之后運行”的排序規(guī)則,您可以指定 taskB 必須總是運行在 taskA 之后,無論 taskA 和 taskB 這兩個任務(wù)在什么時候被調(diào)度執(zhí)行。這被表示為 taskB.mustRunAfter(taskA) ?!皯?yīng)該在之后運行”的排序規(guī)則與其類似,但沒有那么嚴(yán)格,因為它在兩種情況下會被忽略。首先是如果使用這一規(guī)則引入了一個排序循環(huán)。其次,當(dāng)使用并行執(zhí)行,并且一個任務(wù)的所有依賴項除了任務(wù)應(yīng)該在之后運行之外所有條件已滿足,那么這個任務(wù)將會運行,不管它的“應(yīng)該在之后運行”的依賴項是否已經(jīng)運行了。當(dāng)傾向于更快的反饋時,會使用“應(yīng)該在之后運行”的規(guī)則,因為這種排序很有幫助但要求不嚴(yán)格。

目前使用這些規(guī)則仍有可能出現(xiàn) taskA 執(zhí)行而 taskB 沒有執(zhí)行,或者 taskB 執(zhí)行而 taskA 沒有執(zhí)行。

添加 '必須在之后運行 ' 的任務(wù)排序

build.gradle

task taskX << {
    println 'taskX'
}
task taskY << {
    println 'taskY'
}
taskY.mustRunAfter taskX  

gradle -q taskY taskX 的輸出結(jié)果

> gradle -q taskY taskX
taskX
taskY  

添加 '應(yīng)該在之后運行 ' 的任務(wù)排序

build.gradle

task taskX << {
    println 'taskX'
}
task taskY << {
    println 'taskY'
}
taskY.shouldRunAfter taskX  

gradle -q taskY taskX 的輸出結(jié)果

> gradle -q taskY taskX
taskX
taskY  

在上面的例子中,它仍有可能執(zhí)行 taskY 而不會導(dǎo)致 taskX 也運行:

任務(wù)排序并不意味著任務(wù)執(zhí)行

gradle -q taskY 的輸出結(jié)果

> gradle -q taskY
taskY  

如果想指定兩個任務(wù)之間的“必須在之后運行”和“應(yīng)該在之后運行”排序,可以使用 Task.mustRunAfter() 和 Task.shouldRunAfter() 方法。這些方法接受一個任務(wù)實例、 任務(wù)名稱或 Task.dependsOn()所接受的任何其他輸入作為參數(shù)。

請注意"B.mustRunAfter(A)"或"B.shouldRunAfter(A)"并不意味著這些任務(wù)之間的任何執(zhí)行上的依賴關(guān)系:

  • 它是可以獨立地執(zhí)行任務(wù) A 和 B 的。排序規(guī)則僅在這兩項任務(wù)計劃執(zhí)行時起作用。
  • 當(dāng)--continue 參數(shù)運行時,可能會是 A 執(zhí)行失敗后B執(zhí)行了。

如之前所述,如果“應(yīng)該在之后運行”的排序規(guī)則引入了排序循環(huán),那么它將會被忽略。

當(dāng)引入循環(huán)時,“應(yīng)該在其之后運行”的任務(wù)排序會被忽略

build.gradle

task taskX << {
    println 'taskX'
}
task taskY << {
    println 'taskY'
}
task taskZ << {
    println 'taskZ'
}
taskX.dependsOn taskY
taskY.dependsOn taskZ
taskZ.shouldRunAfter taskX  

gradle -q taskX 的輸出結(jié)果

> gradle -q taskX
taskZ
taskY
taskX  

向任務(wù)添加描述

你可以向你的任務(wù)添加描述。例如,當(dāng)執(zhí)行 gradle tasks 時顯示這個描述。

向任務(wù)添加描述

build.gradle

task copy(type: Copy) {
   description 'Copies the resource directory to the target directory.'
   from 'resources'
   into 'target'
   include('**/*.txt', '**/*.xml', '**/*.properties')
}  

替換任務(wù)

有時您想要替換一個任務(wù)。例如,您想要把通過 Java 插件添加的一個任務(wù)與不同類型的一個自定義任務(wù)進(jìn)行交換。你可以這樣實現(xiàn):

重寫任務(wù)

build.gradle

task copy(type: Copy)
task copy(overwrite: true) << {
    println('I am the new one.')
}  

gradle -q copy 的輸出結(jié)果

> gradle -q copy
I am the new one.  

在這里我們用一個簡單的任務(wù)替換 Copy 類型的任務(wù)。當(dāng)創(chuàng)建這個簡單的任務(wù)時,您必須將 overwrite 屬性設(shè)置為 true。否則 Gradle 將拋出異常,說這種名稱的任務(wù)已經(jīng)存在。

跳過任務(wù)

Gradle 提供多種方式來跳過任務(wù)的執(zhí)行。

使用斷言

你可以使用 onlyIf()方法將斷言附加到一項任務(wù)中。如果斷言結(jié)果為 true,才會執(zhí)行任務(wù)的操作。你可以用一個閉包來實現(xiàn)斷言。閉包會作為一個參數(shù)傳給任務(wù),并且任務(wù)應(yīng)該執(zhí)行時返回 true,或任務(wù)應(yīng)該跳過時返回 false。斷言只在任務(wù)要執(zhí)行前才計算。

使用斷言跳過一個任務(wù)

build.gradle

task hello << {
    println 'hello world'
}
hello.onlyIf { !project.hasProperty('skipHello') }  

gradle hello -PskipHello 的輸出結(jié)果

> gradle hello -PskipHello
:hello SKIPPED
BUILD SUCCESSFUL
Total time: 1 secs  

使用 StopExecutionException

如果跳過任務(wù)的規(guī)則不能與斷言同時表達(dá),您可以使用 StopExecutionException。如果一個操作(action)拋出了此異常,那么這個操作(action)接下來的行為和這個任務(wù)的其他 操作(action)都會被跳過。構(gòu)建會繼續(xù)執(zhí)行下一個任務(wù)。

使用 StopExecutionException 跳過任務(wù)

build.gradle

task compile << {
    println 'We are doing the compile.'
}
compile.doFirst {
    // Here you would put arbitrary conditions in real life. But we use this as an integration test, so we want defined behavior.
    if (true) { throw new StopExecutionException() }
}
task myTask(dependsOn: 'compile') << {
   println 'I am not affected'
}  

gradle -q myTask 的輸出結(jié)果

> gradle -q myTask
I am not affected  

如果您使用由 Gradle 提供的任務(wù),那么此功能將非常有用。它允許您向一個任務(wù)的內(nèi)置操作中添加執(zhí)行條件。

啟用和禁用任務(wù)

每一項任務(wù)有一個默認(rèn)值為 true 的 enabled 標(biāo)記。將它設(shè)置為 false,可以不讓這個任務(wù)的任何操作執(zhí)行。

啟用和禁用任務(wù)

build.gradle

task disableMe << {
    println 'This should not be printed if the task is disabled.'
}
disableMe.enabled = false  

Gradle disableMe 的輸出結(jié)果

> gradle disableMe
:disableMe SKIPPED
BUILD SUCCESSFUL
Total time: 1 secs  

跳過處于最新狀態(tài)的任務(wù)

如果您使用 Gradle 自帶的任務(wù),如 Java 插件所添加的任務(wù)的話,你可能已經(jīng)注意到 Gradle 將跳過處于最新狀態(tài)的任務(wù)。這種行在您自己定義的任務(wù)上也有效,而不僅僅是內(nèi)置任務(wù)。

聲明一個任務(wù)的輸入和輸出

讓我們來看一個例子。在這里我們的任務(wù)從一個 XML 源文件生成多個輸出文件。讓我們運行它幾次。

一個生成任務(wù)

build.gradle

task transform {
    ext.srcFile = file('mountains.xml')
    ext.destDir = new File(buildDir, 'generated')
    doLast {
        println "Transforming source file."
        destDir.mkdirs()
        def mountains = new XmlParser().parse(srcFile)
        mountains.mountain.each { mountain ->
            def name = mountain.name[0].text()
            def height = mountain.height[0].text()
            def destFile = new File(destDir, "${name}.txt")
            destFile.text = "$name -> ${height}\n"
        }
    }
}  

gradle transform 的輸出結(jié)果

> gradle transform
:transform
Transforming source file.  

gradle transform的輸出結(jié)果

> gradle transform
:transform
Transforming source file.  

請注意 Gradle 第二次執(zhí)行執(zhí)行這項任務(wù)時,即使什么都未作改變,也沒有跳過該任務(wù)。我們的示例任務(wù)被用一個操作(action)閉包來定義。Gradle 不知道這個閉包做了什么,也無法自動判斷這個任務(wù)是否為最新狀態(tài)。若要使用 Gradle 的最新狀態(tài)(up-to-date)檢查,您需要聲明這個任務(wù)的輸入和輸出。

每個任務(wù)都有一個 inputs 和 outputs 的屬性,用來聲明任務(wù)的輸入和輸出。下面,我們修改了我們的示例,聲明它將 XML 源文件作為輸入,并產(chǎn)生輸出到一個目標(biāo)目錄。讓我們運行它幾次。

聲明一個任務(wù)的輸入和輸出

build.gradle

task transform {
    ext.srcFile = file('mountains.xml')
    ext.destDir = new File(buildDir, 'generated')
    inputs.file srcFile
    outputs.dir destDir
    doLast {
        println "Transforming source file."
        destDir.mkdirs()
        def mountains = new XmlParser().parse(srcFile)
        mountains.mountain.each { mountain ->
            def name = mountain.name[0].text()
            def height = mountain.height[0].text()
            def destFile = new File(destDir, "${name}.txt")
            destFile.text = "$name -> ${height}\n"
        }
    }
}  

gradle transform 的輸出結(jié)果

> gradle transform
:transform
Transforming source file.  

gradle transform 的輸出結(jié)果

> gradle transform
:transform UP-TO-DATE  

現(xiàn)在,Gradle 知道哪些文件要檢查以確定任務(wù)是否為最新狀態(tài)。

任務(wù)的 inputs 屬性是 TaskInputs 類型。任務(wù)的 outputs 屬性是 TaskOutputs 類型。

一個沒有定義輸出的任務(wù)將永遠(yuǎn)不會被當(dāng)作是最新的。對于任務(wù)的輸出并不是文件的場景,或者是更復(fù)雜的場景, TaskOutputs.upToDateWhen() 方法允許您以編程方式計算任務(wù)的輸出是否應(yīng)該被判斷為最新狀態(tài)。

一個只定義了輸出的任務(wù),如果自上一次構(gòu)建以來它的輸出沒有改變,那么它會被判定為最新狀態(tài)。

它是怎么實現(xiàn)的?

在第一次執(zhí)行任務(wù)之前,Gradle 對輸入進(jìn)行一次快照。這個快照包含了輸入文件集和每個文件的內(nèi)容的哈希值。然后 Gradle 執(zhí)行該任務(wù)。如果任務(wù)成功完成,Gradle 將對輸出進(jìn)行一次快照。該快照包含輸出文件集和每個文件的內(nèi)容的哈希值。Gradle 會保存這兩個快照,直到任務(wù)的下一次執(zhí)行。

之后每一次,在執(zhí)行任務(wù)之前,Gradle 會對輸入和輸出進(jìn)行一次新的快照。如果新的快照和前一次的快照一樣,Gradle 會假定這些輸出是最新狀態(tài)的并跳過該任務(wù)。如果它們不一則, Gradle 則會執(zhí)行該任務(wù)。Gradle 會保存這兩個快照,直到任務(wù)的下一次執(zhí)行。

請注意,如果一個任務(wù)有一個指定的輸出目錄,在它上一次執(zhí)行之后添加到該目錄的所有文件都將被忽略,并且不會使這個任務(wù)成為過時狀態(tài)。這是不相關(guān)的任務(wù)可以在不互相干擾的情況下共用一個輸出目錄。如果你因為一些理由而不想這樣,請考慮使用 TaskOutputs.upToDateWhen()

任務(wù)規(guī)則

有時你想要有這樣一項任務(wù),它的行為依賴于參數(shù)數(shù)值范圍的一個大數(shù)或是無限的數(shù)字。任務(wù)規(guī)則是提供此類任務(wù)的一個很好的表達(dá)方式:

任務(wù)規(guī)則

build.gradle

tasks.addRule("Pattern: ping<ID>") { String taskName ->
    if (taskName.startsWith("ping")) {
        task(taskName) << {
            println "Pinging: " + (taskName - 'ping')
        }
    }
}  

Gradle q pingServer1 的輸出結(jié)果

> gradle -q pingServer1
Pinging: Server1  

這個字符串參數(shù)被用作這條規(guī)則的描述。當(dāng)對這個例子運行 gradle tasks 的時候,這個描述會被顯示。

規(guī)則不只是從命令行調(diào)用任務(wù)才起作用。你也可以對基于規(guī)則的任務(wù)創(chuàng)建依賴關(guān)系:

基于規(guī)則的任務(wù)依賴

build.gradle

tasks.addRule("Pattern: ping<ID>") { String taskName ->
    if (taskName.startsWith("ping")) {
        task(taskName) << {
            println "Pinging: " + (taskName - 'ping')
        }
    }
}
task groupPing {
    dependsOn pingServer1, pingServer2
}  

Gradle q groupPing 的輸出結(jié)果

> gradle -q groupPing
Pinging: Server1
Pinging: Server2  

析構(gòu)器任務(wù)

析構(gòu)器任務(wù)是一個孵化中的功能 。當(dāng)最終的任務(wù)準(zhǔn)備運行時,析構(gòu)器任務(wù)會自動地添加到任務(wù)圖中。

添加一個析構(gòu)器任務(wù)

build.gradle

task taskX << {
    println 'taskX'
}
task taskY << {
    println 'taskY'
}
taskX.finalizedBy taskY  

gradle -q taskX 的輸出結(jié)果

> gradle -q taskX
taskX
taskY  

即使最終的任務(wù)執(zhí)行失敗,析構(gòu)器任務(wù)也會被執(zhí)行。

執(zhí)行失敗的任務(wù)的任務(wù)析構(gòu)器

build.gradle

task taskX << {
    println 'taskX'
    throw new RuntimeException()
}
task taskY << {
    println 'taskY'
}
taskX.finalizedBy taskY  

gradle -q taskX 的輸出結(jié)果

> gradle -q taskX
taskX
taskY  

另一方面,如果最終的任務(wù)什么都不做的話,比如由于失敗的任務(wù)依賴項或如果它被認(rèn)為是最新的狀態(tài),析構(gòu)任務(wù)不會執(zhí)行。

在不管構(gòu)建成功或是失敗,都必須清理創(chuàng)建的資源的情況下,析構(gòu)認(rèn)為是很有用的。這樣的資源的一個例子是,一個 web 容器會在集成測試任務(wù)前開始,并且在之后關(guān)閉,即使有些測試失敗。

你可以使用 Task.finalizedBy()方法指定一個析構(gòu)器任務(wù)。這個方法接受一個任務(wù)實例、任務(wù)名稱或<a4><c5>Task.dependsOn()</c5></a4>所接受的任何其他輸入作為參數(shù)。

總結(jié)

如果你是從 Ant 轉(zhuǎn)過來的,像 Copy 這種增強的 Gradle 任務(wù),看起來就像是一個 Ant 目標(biāo)(target)和一個 Ant 任務(wù)(task)之間的混合物。實際上確實是這樣子。Gradle 沒有像 Ant 那樣對任務(wù)和目標(biāo)進(jìn)行分離。簡單的 Gradle 任務(wù)就像 Ant 的目標(biāo),而增強的 Gradle 任務(wù)還包括 Ant 任務(wù)方面的內(nèi)容。Gradle 的所有任務(wù)共享一個公共 API,您可以創(chuàng)建它們之間的依賴性。這樣的一個任務(wù)可能會比一個 Ant 任務(wù)更好配置。它充分利用了類型系統(tǒng),更具有表現(xiàn)力而且易于維護(hù)。

上一篇:Groovy 插件下一篇:Gradle 插件