全面理解Gradle - 執行時序

什麼是Gradle?

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

如何學習Gradle?

使用Gradle wrapper

若是你本地安裝了Gradle,那麼你就可使用gradle命令來直接構建。若是本地沒有安裝,那麼能夠經過gradle wrapper來構建,Linux和MAC使用./gradlew,而Windows上面則使用gradlew,還能夠在 gradle/gradle-wrapper.properties 中配置 Gradle 版本。java

Gradle腳本的執行時序

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

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

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

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

下面咱們根據一個實際的例子來詳細說明。這裏咱們仍然採用VirtualAPK這個開源項目來作演示,它的地址是:https://github.com/didi/VirtualAPK數據結構

咱們以它的宿主端爲例,宿主端有以下幾個模塊: 
這裏寫圖片描述 
其實buildSrc是virtualapk-gradle-plugin,爲了便於調試我將其重命名爲buildSrc。他們的依賴關係以下:app

這裏寫圖片描述

解釋一下,app模塊依賴CoreLibrary和buildSrc,CoreLibrary又依賴AndroidStub。爲了你們更好理解,下面加一下log。框架

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

println "settings start"
include ':app'
include ':CoreLibrary'
include ':AndroidStub'
println "settings end"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
/***** VirtualAPK.gradle *****/

println "virtualapk start"

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

task clean(type: Delete) {
    delete rootProject.buildDir
}
println "virtualapk end"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
/***** 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"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
/***** 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"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
/***** AndroidStub.gradle *****/

println "androidstub config start"

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

println "androidstub config end"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
/***** 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"

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

如今隨便執行一個task,好比./gradlew clean,那麼將會輸出以下日誌,你們對比着日誌,應該能明白Gradle腳本的執行順序了吧。maven

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

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

備註:若是註冊了多個project.afterEvaluate回調,那麼執行順序等同於註冊順序。在上面的例子中,因爲buildSrc中的回調註冊較早,因此它也先執行。

本公衆號聚焦於『Android開發前沿、AI技術、職業發展、生活感悟、妹子圖』,歡迎你們關注: 

相關文章
相關標籤/搜索