上文 講述了 Gradle 中關於任務的基礎概念,本文開始講述下 Task 是如何定義的。java
爲了方便,咱們的語境分不開Gradle
和Android Gradle Plugin
,所以此處不脫離Android
環境來介紹Gradle
。
咱們在講述任務依賴的時候,提到一個Manager
的東西,在這裏,咱們說到的是Android Gradle Plugin
提供的BuildableArtifactsHolder
這個類。api
一個 Task 若是有有意義的輸出,且產物可能被其餘的 Task 所使用的時候,咱們能夠往BuildableArtifactsHolder
註冊咱們的產物,註冊方式有這麼幾種:app
createBuildableArtifact/createDirectory/createArtifactFile
這些 api 須要傳入建立文件的類型,文件的文件名,動做等,以createArtifactFile
的其中一種形式爲例:ide
fun createArtifactFile( artifactType: ArtifactType, operationType: OperationType, taskName: String, fileName: String) : Provider<RegularFile>
artifactType
就是產物類型函數
operationType
是操做類型,能夠是初始化(init),追加(append),或者變化(transform),區別以下:gradle
你能夠根據你使用產物的目的來使用不一樣類型,由於返回值是一個 FileCollection (文件集合,不是文件夾的概念),若是調用的是 transform,你須要注意在 Configuration 階段對於這些產物調用順序的問題,若是 B.transform 在 A.transform 以後,那麼獲取最終產物的時候,就會取走 B 的結果。ui
BuildableArtifactsHolder 提供的 api 通常都已經讓你傳入了 taskName,就是讓你告訴它,你所產生的產物由哪一個任務生成。後續你去根據 artifactType 獲取產物(FileCollection)的時候,它會檢查這個任務是否執行,若是沒有的話會先執行,這部分判斷的邏輯由 FileCollection 的 builtBy 作到,由 Gradle 進行管理。spa
以上,咱們介紹瞭如何讓 Task 的產物和 Task 自己產生一些關聯,這種關聯創建完成以後,能夠看到 createArtifactFile 這個函數的返回值是Provider<RegularFile>
,這裏表明了一個目的地,咱們往這個文件裏寫入的產物便可;固然這裏也能夠建立文件夾同理,示例代碼:code
task.outputFile = variantScope.getArtifacts().createArtifactFile( InternalArtifactType.BUNDLE, BuildArtifactsHolder.OperationType.INITIAL, taskName, bundleName)
而後在 task 定義的地方:orm
class Task { private Provider<RegularFile> outputFile; @OutputFile public Flie getOutputFile() { return outputFile.get().asFile(); } }
這樣的話,gradle 會自動幫你建立這個文件,開發者須要的只是調用getOutputFile()
拿到File
而後寫入便可。
咱們知道了 Task 產生一個文件的完整流程,咱們該如何使用這個文件呢?咱們在另一個 Task 中,定義一下 input
task.input = variantScope.getArtifacts().getArtifactFiles(type); //這裏的 type 和上面的type同樣,好比 InternalArtifactType.BUNDLE
這個拿到是一個 BuildableArtifact 對象,它的聲明以下:
interface BuildableArtifact : Iterable<File>, Buildable, Supplier<FileCollection> { val files : Set<File> fun isEmpty() : Boolean }
可使用get()
獲取一個FileCollection
,當再次調用FileCollection.getFiles()
方法時,gradle 就會檢查產生這個產物的 Task 是否已經執行,若是沒有執行,就會先執行前面一個 Task
歡迎關注個人公衆號「TalkWithMobile」