上一章知道如何自定義 Gradle插件后邑时,我們到底可以用來做什么呢锚烦?難道只是用來定義一些簡(jiǎn)單的 Task牙言?本章給你答案跟匆!
什么是 Transform API
Android Gradle 工具從 1.5.0-beta1
版本開始赞赖,包含了 Transform API滚朵,它允許第三方插件在將編譯后的類文件轉(zhuǎn)換為 dex 文件之前對(duì) .class 文件進(jìn)行操作。
Transform 的工作原理
接下來看下它的工作原理:
- 很明顯它是一個(gè)鏈?zhǔn)浇Y(jié)構(gòu)前域,每個(gè) Transform 都是一個(gè) Gradle 的 Task辕近,Android 編譯器通過 TaskManager 將每個(gè) Transform 串聯(lián)起來。
- 第一個(gè) Transform 接收 javac 編譯的結(jié)果匿垄,以及 jar 包依賴和 resource 資源移宅,這些編譯的中間產(chǎn)物在 Transform 鏈上流動(dòng)。其中椿疗,我們自定義的 Transform 會(huì)插入到最前面
Transform API 的使用
Transform API 其實(shí)就是繼承自 Transform 寫一個(gè)實(shí)現(xiàn)類漏峰,我們看下 Transform 需要實(shí)現(xiàn)的方法:
簡(jiǎn)單介紹下這幾個(gè)方法:
getName():用于指定 Transform 的名字,對(duì)應(yīng)了該 Transform 所代表的 Task 的名稱届榄,例如:
isIncremental():方法指明是否支持增量編譯浅乔。
getInputTypes():用于指定 Transform 的輸入類型,可以作為輸入過濾的一種手段痒蓬。在 TransformManager 中定義了很多類型:
- CONTENT_CLASS // 代表 javac 編譯成的 class 文件(一般用它)
- CONTENT_JARS
- CONTENT_RESOURCES // 這里的 resources 單指 java 的資源
- CONTENT_NATIVE_LIBS
- CONTENT_DEX
- CONTENT_DEX_WITH_RESOURCES
- DATA_BINDING_BASE_CLASS_LOG_ARTIFACT
getScopes():用于指定 Transform 的作用域童擎。同樣在 TransformManager 中定義了很多類型,常用的是 SCOPE_FULL_PROJECT攻晒,即代表所有 Project顾复。
確定了 ContentType 和 Scope 后就確定了該自定義 Transform 需要處理的資源流。
例如鲁捏,上面提到的常用輸入類型(CONTENT_CLASS)和常用作用域(SCOPE_FULL_PROJECT)表示的就是 所有項(xiàng)目中 java 編譯成的 class 組成的資源流芯砸。
接下來我們來看需要復(fù)寫的核心方法:
TransformInvocation 接口定義如下:
看下 TransformInput 的接口定義:
所謂 Transform 就是對(duì)輸入的 class 文件轉(zhuǎn)變成目標(biāo)字節(jié)碼文件,TransformInput 就是這些輸入文件的抽象给梅。目前它包括兩部分:DirectoryInput 集合與 JarInput 集合假丧。
TransformOutputProvider 通過調(diào)用 getContentLocation 來獲取輸出目錄:
復(fù)寫完 Transform 的核心方法之后,我們需要通過插件注冊(cè)它才可使用:
整體看下 CustomTransform 類:
接下來看下讀取 class 文件的流程:
Demo 工程
Android 工程:https://github.com/changer0/ASMInjectDemo
以上就是本節(jié)內(nèi)容动羽,歡迎大家關(guān)注??????