Gradle插件運(yùn)行流程整理

上面兩篇文章值得多看幾遍,下面是簡單的總結(jié):

在build.gradle文件開始,有apply plugin,

apply plugin: 'com.android.application' //對(duì)應(yīng)apk
apply plugin: 'com.android.library' //對(duì)應(yīng)aar

調(diào)用鏈:
app工程 -> AppPlugin -> AppExtension
library工程 -> LibraryPlugin -> LibraryExtension

library工程和app工程類似,下面只看app工程

AppPlugin extends BasePlugin

查看BasePlugin 的 apply,主要執(zhí)行了這三步驟:

1.configureProject
2.configureExtension
3.createTasks

configureProject

主要作用:

  1. 進(jìn)行版本有效性的判斷。
  2. 創(chuàng)建了 AndroidBuilder 對(duì)象,后面用來合并manifest 和創(chuàng)建 dex 等作用。
  3. 設(shè)置了構(gòu)建流程的回調(diào)來處理依賴和dex的加載和緩存清理。

跟蹤代碼:

  1. project.afterEvaluate回調(diào)里執(zhí)行了setSdkLibData
  2. new AndroidBuilder
  3. getGradle().addBuildListener的finish回調(diào)里執(zhí)行PreDexCache的清理
  4. getGradle().getTaskGraph().addTaskExecutionGraphListener,將TransformTask加載進(jìn)PreDexCache

configureExtension

主要作用:

創(chuàng)建 Android 插件的擴(kuò)展對(duì)象,對(duì)配置項(xiàng) BuildType、ProductFlavor、SigningConfig 做了統(tǒng)一的創(chuàng)建和回調(diào)處理, 創(chuàng)建taskManager、variantFactory、variantManager。

android {
    compileSdkVersion COMPILE_SDK_VERSION
    ……
    defaultConfig {
        ……
    }

    buildTypes {
        ……
    }
    ……
}

1、創(chuàng)建了 BuildType、ProductFlavor、SigningConfig 三個(gè)類型的Container
2、createExtension具體實(shí)現(xiàn)在AppPlugin里,這個(gè)方法就是創(chuàng)建android配置,將上面new出來的各個(gè)類傳進(jìn)去,最終生成AppExtension
3、之后創(chuàng)建了一些管理類
DependencyManager
NdkHandler
createTaskManager :就是創(chuàng)建具體任務(wù)的管理類
createVariantFactory
VariantManager:VariantFactory 構(gòu)建變體的工廠類,主要是生成Variant的對(duì)象
register ModelBuilder

注意:最下面是BuildType、ProductFlavor、SigningConfig 三個(gè)類型的Container增加whenObjectAdded監(jiān)聽,可以看到回調(diào)里都調(diào)用了variantManager::add……方法

createTasks

利用上面的兩種配置,進(jìn)行任務(wù)的創(chuàng)建。

任務(wù)有兩種,一個(gè)是在 beforeEvaluate 創(chuàng)建任務(wù);一個(gè)是在 afterEvaluate 創(chuàng)建任務(wù)。
beforeEvaluate跟我們編譯沒有太大關(guān)系。AndroidTask 是依賴配置項(xiàng)的配置才能生成相應(yīng)任務(wù),所以在afterEvaluate 回調(diào)里創(chuàng)建。

下面Gradle 提供的生命周期回調(diào)執(zhí)行順序:

settings:執(zhí)行settingsEvaluated...
settings:執(zhí)行projectsLoaded...
settings:執(zhí)行test beforeProject
根項(xiàng)目配置開始---
根項(xiàng)目里任務(wù)配置---
根項(xiàng)目配置結(jié)束---
settings:執(zhí)行test afterProject
settings:執(zhí)行app beforeProject
子項(xiàng)目beforeEvaluate回調(diào)...
APP子項(xiàng)目配置開始---
APP子項(xiàng)目里任務(wù)配置---
APP子項(xiàng)目配置結(jié)束---
settings:執(zhí)行app afterProject
APP子項(xiàng)目afterEvaluate回調(diào)...
settings: 執(zhí)行projectsEvaluated...
構(gòu)建結(jié)束...

createAndroidTasks -> variantManager的createAndroidTasks

if (variantDataList.isEmpty()) {
     this::populateVariantDataList);//創(chuàng)建variantDataList
}
taskManager.createTopLevelTestTasks
createTasksForVariantData

populateVariantDataList 構(gòu)建變體任務(wù):
利用buildType 和 productFlavor ,構(gòu)建 variantData,舉例:
BuildType :release、debug
productFlavor:push、dot(打點(diǎn))
生成兩個(gè)variantData
{release+(push、dot)}、{debug+(push、dot)}

createTasksForVariantData :createAssembleTaskForVariantData方法
assemble任務(wù)

  1. 首先會(huì)先根據(jù) buildType 信息創(chuàng)建 assemble + buildType 的任務(wù),可以看下taskManager. createAssembleTask里的代碼
  2. 將assemble任務(wù)依賴于我們的assembleXXX任務(wù),創(chuàng)建 assemble + flavor + buildType 任務(wù),流程多了 productFlavor 任務(wù)的創(chuàng)建。
    舉例:
    創(chuàng)建assembleRelease,再創(chuàng)建assemblePushRelease,assembleDotRelease
    創(chuàng)建assembleDebug,再創(chuàng)建assemblePushDebug,assembleDotDebug

createTasksForVariantData 的 taskManager.createTasksForVariantData方法:

生成 variantData 的一系列像 compileXXX、generateXXX、processXXX、mergeXXX的任務(wù),具體代碼再ApplicationTaskManager

在createPostCompilationTasks中,
如果設(shè)置了 minifyEnabled 為 true,會(huì)創(chuàng)建 createMinifyTransform ,
如果use proguard,這里會(huì)創(chuàng)建 progruad 的任務(wù)和 shrinkResources 的任務(wù)。
后面將創(chuàng)建 dexTask, 這個(gè)是 transfromTask 類型的任務(wù)

dexTask 中傳入的 transfrom 是DexTransfrom,會(huì)調(diào)用 DexTransfrom 的 transfrom ,
自定義的transfrom就是把主要邏輯寫在transform里。

transfrom方法執(zhí)行到androidBuilder.convertByteCode。主要做了:
1.通過執(zhí)行 processAllFiles ,內(nèi)部創(chuàng)建 DexFile 也就是outputDex,并且填充 class 文件
2.通過 writeDex 方法,將 outputDex 傳入,方法內(nèi)部執(zhí)行的是 outputDex.toDex 方法,將 outputDex 內(nèi)部填充的 class 轉(zhuǎn)化為 dex 的 byte[] 返回
3.最后將 byte[] 數(shù)組創(chuàng)建 classes.dex 輸出

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文由玉剛說寫作平臺(tái)提供寫作贊助,版權(quán)歸玉剛說微信公眾號(hào)所有原作者:ShinyZeng版權(quán)聲明:未經(jīng)玉剛說許可,不...
    渡過閱讀 11,060評(píng)論 3 30
  • 1.介紹 如果你正在查閱build.gradle文件的所有可選項(xiàng),請(qǐng)點(diǎn)擊這里進(jìn)行查閱:DSL參考 1.1新構(gòu)建系統(tǒng)...
    Chuckiefan閱讀 12,357評(píng)論 8 72
  • Android Gradle為我們提供了大量的DSL,我們使用這些DSL定義配置我們的工程以滿足我們項(xiàng)目中不同的需...
    acc8226閱讀 1,128評(píng)論 0 7
  • 最近在學(xué)習(xí)自定義Gradle插件,怎么說呢,過程相對(duì)曲折,結(jié)果相對(duì)滿意。在涉及到Gradle時(shí)也愿意去更多的了解一...
    MIAN勉閱讀 8,539評(píng)論 0 5
  • 續(xù)上篇。 他很少很少想過三年后的自己會(huì)怎樣。對(duì)未來的想象和期望,他認(rèn)為那就像海市蜃樓,是假象。 記得09年讀高三,...
    王昌倫閱讀 447評(píng)論 2 2

友情鏈接更多精彩內(nèi)容