Gradle小知識#1:tasks

原文鏈接 : Gradle tip #1: tasks

從這篇博文開始我打算開啟關于Gradle相關知識的一些列博文。現在想想,如果我剛開始接觸Gradle的時候知道這些知識的話那該多好啊。

今天我們來聊聊Gradle的任務,尤其是任務的配置和執行部分。因為這塊知識對很多讀者來說還不是很清楚,所以通過一個真實的例子來說明下就再好不過了。大體上(抱歉有點超前)我們是想要弄清楚下面這三個例子到底有啥區別:

task myTask {
    println "Hello, World!"
}

task myTask {
    doLast {
        println "Hello, World!"
    }
}

task myTask << {
    println "Hello, World!"
}

我的目的是創建一個任務,當這個任務被執行的時候它能打印"Hello, World!"。一開始,我是這樣實現的:

task myTask {
    println "Hello, World!"
}

現在我們執行下這個任務!

user$ gradle myTask
Hello, World!
:myTask UP-TO-DATE

這好像沒啥問題。正確的打印出了“Hello, World!” 但是,這并沒有按照我們預想的那樣工作。下面讓我告訴你為什么。我們試著調用下gradle tasks看看還有其他什么能執行的任務沒:

user$ gradle tasks
Hello, World!
:tasks

------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------

Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
..........

等等!為什么打印了"Hello, World!"?我只是調用了tasks,我并沒有調用我定義的任務呀!

原因就是在Gradle任務的生命周期中,有兩個重要的階段:

  • 配置階段
  • 執行階段

我對這些專業術語可能不太熟悉,但類比一下可以幫助我更好的理解Gradle的任務。

事情是這樣的,Gradle在真正進行構建之前必須把構建腳本中定義的所有任務配置一下。不管這個任務會不會被執行,它都要先配置一下。

既然了解了這一點,但我又該怎么知道任務中哪部分是在配置階段執行,哪部分又是在執行階段執行呢?答案就是:任務中的頂層部分是配置階段會執行的代碼。比如:

task myTask {
    def name = "Pavel" //<-- this is evaluated during configuration
    println "Hello, World!"http:////<-- this is also evaluated during configuration
}

這就是為什么我只是調用了gradle tasks,但卻打印了"Hello, World!"。因為這部分代碼在配置階段執行了。但這并不是我想要的。我想要的是這段代碼只有在我調用我的任務的時候才去執行。

那么,我該怎么告訴Gradle當我執行我的任務的時候才去做一些事情呢?

這時我就需要給任務指定一個動作。最簡單的做法就是通過Task#doLast()方法:

task myTask {
    def text = 'Hello, World!' //configure my task
    doLast {
        println text //this is executed when my task is called
    }
}

現在,"Hello, World!"只有在我顯式的調用gradle myTask的時候才會打印出來。

Cool!現在我知道怎么配置任務并且讓任務只有在我明確調用的時候才會做真正的工作。那么第三個例子中的<<又是啥?:

task myTask2 << {
    println "Hello, World!" 
}

這只是doLast的簡寫版本而已。這跟下面的寫法完全一樣:

task myTask {
    doLast {
        println 'Hello, World!' //this is executed when my task is called
    }
}

但是,既然所有的代碼都在執行部分了,那我就不能像doLast寫法那樣配置我的任務了(放心吧,還是可以的,只是稍微有點不同而已)。這種簡寫方式對那些不需要進行配置的小任務來說很方便。但是,如果你的任務不僅僅像打印"Hello, World!"這么簡單的話,那還是建議考慮使用doLast這種寫法。


所屬標簽

無標簽

25选5玩法中奖