日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Gradle 使用教程之 Task 详解

發布時間:2023/12/31 综合教程 25 生活家
生活随笔 收集整理的這篇文章主要介紹了 Gradle 使用教程之 Task 详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近打算學習下 gradle 在 Android 中的使用,結果百度出來的文章都是介紹性文章,沒啥干貨。后來找到 gradle 官網教程,自己對著擼。

Gradle 概述:

Gradle 是一個基于 Apache Ant 和 Apache Maven 概念的項目自動化構建工具。它使用一種基于 Groovy 的特定領域語言來聲明項目設置,而不是傳統的 XML。Gradle 就是工程的管理,幫我們做了依賴、打包、部署、發布、各種渠道的差異管理等工作。

Gradle優勢:

一款最新的,功能最強大的構建工具,用它逼格更高

使用程序代替傳統的XML配置,項目構建更靈活

豐富的第三方插件,讓你隨心所欲使用

Maven、Ant能做的,Gradle都能做,但是Gradle能做的,Maven、Ant不一定能做。

Groovy 是一種基于JVM的敏捷開發語言,結合了Python、Ruby和Smalltalk的許多強大的特性。Groovy可以與Java完美結合,而且可以使用Java所有的庫,在語法上支持動態類型、閉包等新一代語言特性,無縫集成所有已經存在的Java類庫,既支持面向對象編程也支持面向過程編程

Groovy 優勢:

一種更加敏捷的編程語言
入門非常的容易,且功能非常的強大
既可以作為編程語言也可以作為腳本語言

剛開始的時候,我對 Gradle 和 Groovy 傻傻分不清楚,以為都是一種語言。后來才懂了,gradle 是一個構建工具,使用的語言是Groovy。

準備工作:

下面進入實戰。

首先為了使用 gradle,大家可以在 Android studio 新建一個 Android 工程。使用其他 IDE 或者需要配置的環境的朋友,可以自己百度相關文章。

文章示例基于 Gradle 5.1.1 構建的。

Task

Gradle 中的所有內容都基于兩個基本概念:項目和任務。

每個 Gradle 構建都由一個或多個項目組成。項目代表什么取決于您在 Gradle 中所做的事情。例如,一個項目可能代表一個 JAR 庫或一個 Web 應用程序。它可能表示從其他項目產生的 JAR 組裝而成的發行版 ZIP。項目不一定代表要構建的事物。它可能表示要完成的事情,例如將應用程序部署到暫存或生產環境。暫時不要擔心這似乎還不清楚。Gradle 的按慣例構建支持為項目的定義添加了更具體的定義。

每個項目由一個或多個任務組成。任務代表構建執行的一些原子工作。這可能是編譯某些類,創建 JAR,生成 Javadoc 或將一些存檔發布到存儲庫。

現在,將研究在一個項目中構建一些簡單的任務。后面的章節將介紹處理多個項目,以及有關處理項目和任務的更多信息。

Hello world

同樣,也是先從 hello world 入門。您可以使用以下gradle命令運行 Gradle 構建。該gradle命令在當前目錄中查找名為build.gradle的文件。這個build.gradle文件稱為構建腳本,盡管嚴格來說,它是一個構建配置腳本,我們將在后面看到。構建腳本定義項目及其任務。

要嘗試此操作,請創建以下名為的構建腳本build.gradle

例子1. 第一個構建腳本,在 android 項目中找到 build.gradle,在里面添加以下代碼:

// build.gradle
task hello {
    doLast {
        println 'Hello world!'
    }
}

在項目的移至包含的目錄并使用以下命令執行構建腳本:

./gradlew -q hello // Android 用戶在根目錄使用 ./gradlew
gradle -q hello  // 非 Android 用戶使用 gradle

使用-q命令行選項運行。這將取消 Gradle 的日志消息,因此僅顯示任務的輸出。這樣可以使示例輸出更加清晰。如果不想,則不需要使用此選項。

后面直接將執行構建腳本的命令放在注釋前,不在單行作為展示了。

定義任務

在這里,你將看到了如何使用字符串作為任務名稱來定義任務。此樣式有一些變體,您可能需要在某些情況下使用。

task('hello') {
    doLast {
        println "hello"
    }
}

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

上面創建了兩個任務分別是 hello 和 copy。有一種定義任務的替代語法,您可能更喜歡使用:

tasks.create('hello') {
    doLast {
        println "hello"
    }
}

tasks.create('copy', Copy) {
    from(file('srcDir'))
    into(buildDir)
}

上面同樣創建了兩個任務分別是 hello 和 copy。最后,Groovy 和 Kotlin DSL 有特定于語言的語法:

// Using Groovy dynamic keywords

task(hello) {
    doLast {
        println "hello"
    }
}

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

采用代碼構建腳本

Gradle 的構建腳本為您提供了 Groovy 和 Kotlin 的全部功能。作為一個開胃菜,看看這個:在Gradle的任務中使用 Groovy 或 Kotlin :

// gradle -q upper
task upper { doLast { String someString = 'mY_nAmE' println "Original: $someString" println "Upper case: ${someString.toUpperCase()}" } }
// gradle -q count
task count { doLast { 4.times { print "$it " } } }

任務之間的依賴

任務之間可以具有依賴性,關鍵字dependsOn :

// gradle -q intro
task hello {
    doLast {
        println 'Hello world!'
    }
}
task intro {
    dependsOn hello
    doLast {
        println "I'm Gradle"
    }
}

上面的依賴是依賴的任務先聲明,然后再進行依賴,還有一種依賴是懶惰性依賴,被依賴的任務可以后面再聲明,但是如果不聲明的會報錯:

// gradle -q taskX 
task taskX {
    dependsOn 'taskY'
    doLast {
        println 'taskX'
    }
}
task taskY {
    doLast {
        println 'taskY'
    }
}

任務taskX 依賴的任務taskY 是后聲明的。

您可以通過多種方式定義任務的依賴關系。在“任務依賴項”中,介紹了使用任務名稱定義依賴項。任務名稱可以引用與該任務在同一項目中的任務,也可以引用其他項目中的任務。要引用另一個項目中的任務,請在任務名稱前添加其所屬項目的路徑。以下是添加從projectA:taskX到的依賴的示例projectB:taskY

// gradle -q taskX
project('projectA') { task taskX { dependsOn ':projectB:taskY' doLast { println 'taskX' } } } project('projectB') { task taskY { doLast { println 'taskY' } } }

此處的projectA,projectB 要改成你項目中的名字,簡單來說,就是不同層級的任務也是可以相互依賴的。

動態任務

Groovy 或 Kotlin 的功能可用于定義任務以外的其他功能。例如,您也可以使用它來動態創建任務。

// gradle -q task1
4.times { counter ->
    task "task$counter" {
        doLast {
            println "I'm task number $counter"
        }
    }
}

上述創建了 4 個 task,分別是 task0,task1,task2,task3。

操作已創建的任務

任務創建后,就可以通過API對其進行訪問。例如,您可以在運行時為任務動態添加依賴項。

// gradle -q task0
4.times { counter ->
    task "task$counter" {
        doLast {
            println "I'm task number $counter"
        }
    }
}
task0.dependsOn task2, task3

或者,您可以將行為添加到現有任務。

// gradle -q hello
task hello { doLast { println 'Hello Earth' } } hello.doFirst { println 'Hello Venus' } hello.configure { doLast { println 'Hello Mars' } } hello.configure { doLast { println 'Hello Jupiter' } }

調用doFirstdoLast可以執行多次。他們將操作添加到任務操作列表的開頭或結尾。執行任務時,將按順序執行操作列表中的操作。

Groovy DSL快捷方式符號

訪問現有任務有一種方便的表示法。每個任務都可以作為構建腳本的屬性來使用:

// gradle -q hello
task hello {
    doLast {
        println 'Hello world!'
    }
}
hello.doLast {
    println "Greetings from the $hello.name task."
}

例子中,通過獲取任務的名字可以知道這個是來自于 task hello 的任務所做的事。這樣可以提高代碼的可讀性,尤其是在使用插件提供的任務(例如compile任務)時。

額外任務屬性

您可以將自己的屬性添加到任務上。要添加名為的屬性myProperty,并為ext.myProperty 設置初始值。就可以像預定義的任務屬性一樣讀取和設置屬性。

// gradle -q printTaskProperties
task myTask {
    ext.myProperty = "myValue"
}

task printTaskProperties {
    doLast {
        println myTask.myProperty
    }
}

默認任務

如果未指定其他任務,則Gradle允許您定義一個或多個默認任務。

// gradle -q
defaultTasks 'clean', 'run'

task clean {
    doLast {
        println 'Default Cleaning!'
    }
}

task run {
    doLast {
        println 'Default Running!'
    }
}

task other {
    doLast {
        println "I'm not a default task!"
    }
}

這等效于運行gradle clean run。在多項目構建中,每個子項目都可以有其自己的特定默認任務。如果子項目未指定默認任務,則使用父項目的默認任務(如果已定義)

通過DAG進行配置

正如我們稍后將詳細描述的(請參閱Build Lifecycle),Gradle具有配置階段和執行階段。在配置階段之后,Gradle 知道應該執行的所有任務。Gradle 為您提供了一個利用此信息的機會。一個用例是檢查發布任務是否在要執行的任務中。以此為基礎,您可以為某些變量分配不同的值。

在以下示例中,distributionrelease任務的執行導致version變量的值不同。

// gradle -q distribution
// gradle -q release
task distribution {
    doLast {
        println "We build the zip with version=$version"
    }
}

task release {
    dependsOn 'distribution'
    doLast {
        println 'We release now'
    }
}

gradle.taskGraph.whenReady { taskGraph ->
    if (taskGraph.hasTask(":release")) {
        version = '1.0'
    } else {
        version = '1.0-SNAPSHOT'
    }
}

可以發現,此處,執行不同的 task 具有不同結果。

構建腳本的外部依賴關系

如果構建腳本需要使用外部庫,則可以將它們添加到構建腳本本身中的腳本的類路徑中。您可以使用buildscript()方法執行此操作,并傳入一個聲明構建腳本類路徑的塊。

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
    }
}

buildscript()方法中的代碼塊將構成ScriptHandler實例。您可以通過向classpath配置添加依賴項來聲明構建腳本類路徑。這與您聲明 Java 編譯類路徑的方式相同。您可以使用除項目依賴項以外的任何依賴項類型。

聲明了構建腳本類路徑后,就可以像在該類路徑上的任何其他類一樣使用構建腳本中的類。以下示例將添加到前面的示例中,并使用構建腳本類路徑中的類。

// gradle -q encode
import org.apache.commons.codec.binary.Base64 buildscript { repositories { mavenCentral() } dependencies { classpath group: 'commons-codec', name: 'commons-codec', version: '1.2' } } task encode { doLast { def byte[] encodedString = new Base64().encode('hello world '.getBytes()) println new String(encodedString) } }

這里先是添加了依賴項,然后再創建了一個任務,引用了依賴項中的類來實現對字符串的加密。

訪問任務的屬性

您通常需要找到在構建文件中定義的任務,例如,對其進行配置或將其用于依賴項。有很多方法可以做到這一點。首先,就像定義任務一樣,Groovy和Kotlin DSL具有特定于語言的語法

task hello
task copy(type: Copy)

// Access tasks using Groovy dynamic properties on Project

println hello.name
println project.hello.name

println copy.destinationDir
println project.copy.destinationDir

任務也可以通過tasks集合獲得。

task hello
task copy(type: Copy)

println tasks.hello.name
println tasks.named('hello').get().name

println tasks.copy.destinationDir
println tasks.named('copy').get().destinationDir

您可以使用tasks.getByPath()方法使用任務的路徑從任何項目訪問任務。您可以getByPath()使用任務名稱,相對路徑或絕對路徑來調用該方法。

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

將參數傳遞給任務構造函數

Task在創建后配置變量的可變屬性相反,您可以將參數值傳遞給Task類的構造函數。為了將值傳遞給Task構造函數,您必須使用注釋相關的構造函數@javax.inject.Inject

class CustomTask extends DefaultTask {
    final String message
    final int number

    @Inject
    CustomTask(String message, int number) {
        this.message = message
        this.number = number
    }
}

然后,您可以創建一個任務,并在參數列表的末尾傳遞構造函數參數。

tasks.create('myTask', CustomTask, 'hello', 42)
task myTask(type: CustomTask, constructorArgs: ['hello', 42])

上述兩種方法都可以。在所有情況下,作為構造函數參數傳遞的值都必須為非 null。如果您嘗試傳遞一個null值,Gradle 將拋出一個NullPointerException指示,指出哪個運行時值是null

向任務添加描述

您可以在任務中添加描述。執行 gradle tasks 時將顯示此描述。

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

更換任務

有時您想替換任務。例如,如果要將 Java 插件添加的任務與其他類型的自定義任務交換。您可以使用以下方法實現此目的:

// gradle -q copy
task copy(type: Copy)

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

定義新任務時,必須將overwrite屬性設置為 true。否則,Gradle 會引發異常,說該名稱的任務已經存在。

跳過任務

Gradle 提供了多種方法來跳過任務的執行。

使用謂詞

您可以使用該onlyIf()方法將謂詞附加到任務。僅當謂詞評估為 true 時,才執行任務的動作。您將謂詞實現為閉包。閉包作為參數傳遞給任務,如果任務應執行,則應返回 true;如果應跳過任務,則應返回 false。在即將執行任務之前就對謂詞進行評估。

// gradle hello -PskipHello
task hello { doLast { println 'hello world' } } hello.onlyIf { !project.hasProperty('skipHello') }

使用StopExecutionException

如果不能用謂詞來表示跳過任務的邏輯,則可以使用StopExecutionException。如果某個動作引發了此異常,則將跳過該動作的進一步執行以及該任務的任何后續動作的執行。構建繼續執行下一個任務。

// gradle -q myTask
task compile {
    doLast {
        println 'We are doing the compile.'
    }
}

compile.doFirst {
    // Here you would put arbitrary conditions in real life.
    // But this is used in an integration test so we want defined behavior.
    if (true) { throw new StopExecutionException() }
}
task myTask {
    dependsOn('compile')
    doLast {
        println 'I am not affected'
    }
}

啟用和禁用任務

每個任務都有一個enabled默認為的標志true。將其設置為false阻止執行任何任務動作。禁用的任務將標記為“跳過”。

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

任務超時

每個任務都有一個timeout可用于限制其執行時間的屬性。當任務達到超時時,其任務執行線程將被中斷。該任務將被標記為失敗。終結器任務仍將運行。如果--continue使用,其他任務可以在此之后繼續運行。不響應中斷的任務無法超時。Gradle 的所有內置任務均會及時響應超時

task hangingTask() {
    doLast {
        Thread.sleep(100000)
    }
    timeout = Duration.ofMillis(500)
}

任務規則

有時您想執行一個任務,該任務的行為取決于較大或無限數量的參數值范圍。提供此類任務的一種非常好的表達方式是任務規則:

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

規則不僅在從命令行調用任務時使用。您還可以在基于規則的任務上創建 dependsOn 關系:

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

task groupPing {
    dependsOn pingServer1, pingServer2
}

如果運行“gradle -q tasks”,將找不到名為“pingServer1”或“pingServer2”的任務,但是此腳本正在根據運行這些任務的請求執行邏輯。

Finalizer tasks

當計劃運行終結任務時,Finalizer tasks 會自動添加到任務圖中。

// gradle -q taskX
task taskX { doLast { println 'taskX' } } task taskY { doLast { println 'taskY' } } taskX.finalizedBy taskY

即使終結任務失敗,也將執行 Finalizer tasks。

// gradle -q taskX
task taskX {
    doLast {
        println 'taskX'
        throw new RuntimeException()
    }
}
task taskY {
    doLast {
        println 'taskY'
    }
}

taskX.finalizedBy taskY

運行結果:

Output of gradle -q taskX
> gradle -q taskX
taskX
taskY

FAILURE: Build failed with an exception.

* Where:
Build file '/home/user/gradle/samples/groovy/build.gradle' line: 4

* What went wrong:
Execution failed for task ':taskX'.
> java.lang.RuntimeException (no error message)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 0s

在構建創建無論構建失敗還是成功都必須清除的資源的情況下,終結器任務很有用。這種資源的一個示例是一個Web容器,它在集成測試任務之前啟動,并且即使某些測試失敗,也應始終將其關閉。

要指定終結器任務,請使用Task.finalizedBy(java.lang.Object ...)方法。此方法接受Task實例,任務名稱或Task.dependsOn(java.lang.Object…)接受的任何其他輸入。

到此,關于 task 的講解到這里就結束了。

總結

以上是生活随笔為你收集整理的Gradle 使用教程之 Task 详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。