全面理解Gradle - 執行時序 -开发者知识库

全面理解Gradle - 執行時序 -开发者知识库,第1张

什么是Gradle?

一個像 Ant 一樣的非常靈活的通用構建工具
一種可切換的, 像 maven 一樣的基於合約構建的框架
支持強大的多工程構建
支持強大的依賴管理(基於 ApacheIvy )
支持已有的 maven 和 ivy 倉庫
支持傳遞性依賴管理, 而不需要遠程倉庫或者 pom.xml 或者 ivy 配置文件
優先支持 Ant 式的任務和構建
基於 groovy 的構建腳本
有豐富的領域模型來描述你的構建

如何學習Gradle?

使用Gradle wrapper

如果你本地安裝了Gradle,那么你就可以使用gradle命令來直接構建。如果本地沒有安裝,那么可以通過gradle wrapper來構建,Linux和MAC使用./gradlew,而Windows上面則使用gradlew,還可以在 gradle/gradle-wrapper.properties 中配置 Gradle 版本。

Gradle腳本的執行時序

Gradle腳本的執行分為三個過程:

  • 初始化
    分析有哪些module將要被構建,為每個module創建對應的 project實例。這個時候settings.gradle文件會被解析。

  • 配置:處理所有的模塊的 build 腳本,處理依賴,屬性等。這個時候每個模塊的build.gradle文件會被解析並配置,這個時候會構建整個task的鏈表(這里的鏈表僅僅指存在依賴關系的task的集合,不是數據結構的鏈表)。

  • 執行:根據task鏈表來執行某一個特定的task,這個task所依賴的其他task都將會被提前執行。

下面我們根據一個實際的例子來詳細說明。這里我們仍然采用VirtualAPK這個開源項目來做演示,它的地址是:https://github.com/didi/VirtualAPK

我們以它的宿主端為例,宿主端有如下幾個模塊:
全面理解Gradle - 執行時序 -开发者知识库,這里寫圖片描述,第2张
其實buildSrc是virtualapk-gradle-plugin,為了便於調試我將其重命名為buildSrc。他們的依賴關系如下:

全面理解Gradle - 執行時序 -开发者知识库,這里寫圖片描述,第3张

解釋一下,app模塊依賴CoreLibrary和buildSrc,CoreLibrary又依賴AndroidStub。為了大家更好理解,下面加一下log。

/***** Settings.gradle *****/

println "settings start"
include ':app'
include ':CoreLibrary'
include ':AndroidStub'
println "settings end"
/***** VirtualAPK.gradle *****/

println "virtualapk start"

allprojects {
repositories {
mavenCentral()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
println "virtualapk end"
/***** app.gradle *****/

println "app config start"

apply plugin: 'com.android.application'
apply plugin: 'com.didi.virtualapk.host'

dependencies {
compile project (":CoreLibrary")
}

project.afterEvaluate {
println "app evaluate start"
println "app evaluate end"
}

println "app config end"
/***** CoreLibrary.gradle *****/

apply plugin: 'com.android.library'
println "corelib config start"

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'

provided project(':AndroidStub')
}

apply from: 'upload.gradle'
println "corelib config end"
/***** AndroidStub.gradle *****/

println "androidstub config start"

dependencies {
compile 'com.android.support:support-annotations:22.2.0'
}

println "androidstub config end"
/***** buildSrc *****/

public class VAHostPlugin implements Plugin<Project> {

@Override
public void apply(Project project) {
println "VAHostPlugin config start"

project.afterEvaluate {
println "VAHostPlugin evaluate start"

project.android.applicationVariants.each { ApplicationVariant variant ->
generateDependencies(variant)
backupHostR(variant)
backupProguardMapping(variant)
}
println "VAHostPlugin evaluate end"

}

println "VAHostPlugin config end"

}
}

現在隨便執行一個task,比如./gradlew clean,那么將會輸出如下日志,大家對比着日志,應該能明白Gradle腳本的執行順序了吧。

VirtualAPK renyugang$ ./gradlew clean
settings start
settings end
virtualapk start
virtualapk end
androidstub config start
androidstub config end
Incremental java compilation is an incubating feature.
corelib config start
corelib config end
app config start
VAHostPlugin config start
VAHostPlugin config end
app config end
VAHostPlugin evaluate start
VAHostPlugin evaluate end
app evaluate start
app evaluate end
:clean
:AndroidStub:clean
:CoreLibrary:clean
:app:clean

BUILD SUCCESSFUL

Total time: 12.381 secs

可以看到,Gradle執行的時候遵循如下順序:
1. 首先解析settings.gradle來獲取模塊信息,這是初始化階段;
2. 然后配置每個模塊,配置的時候並不會執行task;
3. 配置完了以后,有一個重要的回調project.afterEvaluate,它表示所有的模塊都已經配置完了,可以准備執行task了;
4. 執行指定的task。

備注:如果注冊了多個project.afterEvaluate回調,那么執行順序等同於注冊順序。在上面的例子中,由於buildSrc中的回調注冊較早,所以它也先執行。

本公眾號聚焦於『Android開發前沿、AI技術、職業發展、生活感悟、妹子圖』,歡迎大家關注:
全面理解Gradle - 執行時序 -开发者知识库,第4张

最佳答案:

本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复