暴力突破 Gradle 自動化項目構建(六)- Gradle 核心之 Task

一、前言


只有 Task 纔可以在 Gradle 的執行階段去執行(其實質是執行的 Task 中的一系列 Action),所以 Task 的重要性不言而喻。

 

二、Task


2.1 Task 定義與配置

Task 的定義方式有如下兩種:

Task 的配置方式也有如下兩種:

配置了 group 後可以在 Android Studio 的 Gradle 面板看到對應的 Task Group 及其分組下的 Tasks,如下圖所示:

一般來說都推薦爲我們的 task 配置 group,便於我們查找 task。另外,group 和 descreption 只是最基本的配置,我們看下 Task 的源碼:

可以看到這些屬性都是可以進行配置的,後面會一一講解。

選型 描述 默認值
name task 名字 無,必須指定
type 需要創建的 task Class DefaultTask
action 當 task 執行的時候,需要執行的閉包 closure 或 行爲 Action null
overwrite 替換一個已存在的 task false
dependsOn 該 task 所依賴的 task 集合 []
group 該 task 所屬組 null
description task 的描述信息 null
constructorArgs 傳遞到 task Class 構造器中的參數 null

 

2.2 Task 執行

上一節我們定義了兩個 task,我們來執行其中一個:

看到上述輸出我們會有個疑問,爲什麼我們執行 helloTask2,但是 helloTask 也被執行輸出了呢?其實很簡單,因爲這兩個 task 都是在 gradle 配置階段執行的,所以我們任何 task 的執行,我們 project 的整個配置代碼都是會執行的,所以這兩個輸出語句都會被執行到。

我們可以通過添加 doFirst 與 doLast 執行動作(Action)爲我們的 task 指定執行階段要執行的代碼,這樣它就只會在 gradle 執行階段去執行。需要注意的是,doFirst 和 doLast 是可以被執行多次的。對於 doFirst 與 doLast 這兩個 Action,它們的作用分別如下所示:

  • doFirst:表示 task 執行最開始的時候被調用的 Action。
  • doLast:表示 task 將執行完的時候被調用的 Action。

我們來驗證下:

接下來,我們就使用 doFirst 與 doLast 來進行一下實戰,來實現計算 build 執行期間的耗時,其完整代碼如下所示:

 

2.3 Task 執行順序

指定 Task 的執行順序有三種方式,如下圖所示:

2.3.1 dependsOn 強依賴方式

dependsOn 強依賴的方式可以細分爲靜態依賴和動態依賴,首先看看靜態依賴,如下所示:

taskZ 依賴 taskX 和 taskY:

執行 taskZ 看看:

可以看到被依賴的 task 先執行,這和我們 java 的繼承關係是很相似的。需要注意的是,這裏 taskX 和 taskY 的執行順序是隨機的。

下面我們再來看看動態依賴:

 

2.3.2 通過Task輸入輸出指定

我們也可以通過 Task 來指定輸入輸出,Task 的輸入輸出對應 TaskInput 和 TaskOutput。下面我們來看一個示例,使用這種方式實現一個自動維護版本發佈文檔的 gradle 腳本,其中輸入輸出相關的代碼如下所示:

首先,我們定義了一個 WirteTask,然後,在註釋1處,指定了輸出文件爲 destFile, 並寫入版本信息到 XML 文件。接着,定義了一個 readTask,並在註釋2處,指定輸入文件爲上一個 task(即 writeTask) 的輸出文件。最後,在註釋3處,使用 dependsOn 將這兩個 task 關聯起來,此時輸入與輸出的順序是會先執行寫入,再執行讀取。這樣,一個輸入輸出的實際案例就實現了。

 

2.3.3 通過API指定執行順序

除了 dependsOn 的方式,我們還可以在 task 閉包中通過 mustRunAfter 方法指定 task 的依賴順序,mustRunAfter 可以指定一個或多個 task,其示例代碼如下所示:

下面我們在命令行中將 taskX、taskY、taskZ 打亂執行:

可以看到最終的執行順序始終是 taskX、taskY、taskZ。

mustRunAfter 是強制指定順序,另外還有一個 shouldRunAfter 不強制性指定,實際應用中一般不會使用 shouldRunAfter,瞭解一下即可。

 

2.4 掛接自定義 task 到構建生命週期

我們可以使用 gradle 提供的一系列生命週期 API 去掛接我們自己的 task 到構建生命週期之中,比如使用 afterEvaluate 方法將我們第三小節定義的 writeTask 掛接到 gradle 配置完所有的 task 之後的時刻,示例代碼如下所示:

 

2.5 Task 類型

除了定義一個新的 task 之外,我們也可以使用 task 的 type 屬性來直接使用一個已有的 task 類型,比如 Gradle 自帶的 Copy、Delete、Sync task 等等。示例代碼如下所示:

更多的 Task 類型我們可以查閱官方文檔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章