不得不學之「 Gradle」 ③ 構建指令碼基礎

Mr.S發表於2019-04-03

其實學到這裡,對於 AndroidStudio 裡的 Gradle 還是不懂, 好多東西見過 ,可是 不知道具體是幹啥的,所以學好基礎,到後面再看 Android Gradle 就很簡 單了 。我 們接著學習基礎。

帶著疑問去學習。

  • 什麼是 Settings 檔案?
  • 什麼是 Build 檔案?
  • 什麼是 Project?
  • 什麼是 Task?

我們在 Gradle 中會經常看到根目錄下有個 settings.gradle

不得不學之「 Gradle」 ③ 構建指令碼基礎

一、setting.gradle

settings.gradle 的作用是為了設定子工程,因為在 Gradle 的多工程是通過工程樹來表示的,其實和 AndroidStudio 中的 project 和 Module 的概念差不多,根工程就是 project,子工程就是 module。

一個子工程只有在 Settins 檔案中配置了才會被 Gradle 識別,也就是才會在構建的時候被包含進去。

rootProject.name = 'mopub-android'
include ':mopub-sdk', ':mopub-sample', ':mopub-sdk:mopub-sdk-base', ':mopub-sdk:mopub-sdk-banner',
        ':mopub-sdk:mopub-sdk-interstitial', ':mopub-sdk:mopub-sdk-rewardedvideo',
        ':mopub-sdk:mopub-sdk-native-static', ':mopub-sdk:mopub-sdk-native-video'
複製程式碼

這裡是為子專案指定預設的目錄,我們也可以手動指定目錄。

include ':mopub-sdk'
project (':mopub-sdk').projectDir = new File(rootDir,'mopub/mopub-sdk')
複製程式碼

二、build.gradle

每一個 Project 都會有一個 build.gradle ,這是該 Project 構建的入口,在這裡對 Project 進行配置,比如依賴哪的庫啊,依賴哪個外掛啊。

雖然每個 Project 都有一個 build.gradle 但是 Root Project 是老大,可以獲取到所有 Child Project ,所以在 Root Project 的 build.gradle 中可以對 Child Project 統一進行配置。比如所有的 Child Project 的倉庫為 jcenter,這樣我們依賴的 jar 就可以直接從 jcenter 中下載了。

buildscript {
    repositories {
        jcenter()
        google()
    }
    ...
}
複製程式碼

Child Project

apply plugin: 'java-library'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.google.auto.service:auto-service:1.0-rc4'
    implementation 'com.squareup:javapoet:1.11.1'
    implementation project(path: ':router_annotation')
}

複製程式碼

3、Projects 和 Tasks

多 Project 其實是為了更好的拆分,低耦合、高聚合,一個專案可以由多個 project 組成,一個 Project 又可以由多個 Task 組成。

比如編譯一次 Java 程式碼,上傳到 JCenter,打包成 aar 等等都是任務。

不得不學之「 Gradle」 ③ 構建指令碼基礎

4、Task。

//檔名為 custom.gradle
ask customTask{
	doFirst{
println ':customTask:doFrist'
	}
	doLast{
println ':customTask:doLast'
	}
}
複製程式碼

不得不學之「 Gradle」 ③ 構建指令碼基礎

5、任務依賴

task Buying  {
	doLast{
	println 'Buying:買菜'
}
}
task Washing(dependsOn: Buying){
	doLast{
println 'Washing:洗菜'
	}
}
task Cook(dependsOn: Washing){
	doLast{
println 'Cook:做飯'
	}
}
複製程式碼

不得不學之「 Gradle」 ③ 構建指令碼基礎

6、任務間通過 API 控制、互動

名稱有點拗口,其實意思就是,比如我們寫了一個 Task ,其實這個 Task 就和我們定義的其他變數一下,可以直接使用 Task 以及他的方法。

task exHello  {
	println '<<'
}
exHello.doFirst{
	println project.hasProperty('exHello')
	println 'doFirst'
}
exHello.doLast{
	println 'doLast'
}
複製程式碼

不得不學之「 Gradle」 ③ 構建指令碼基礎

7、自定義屬性

這個我們就用的比較多了,基本都會使用到。如果需要新增額外的自定義屬性,那麼可以通過兩種方式,一種是 ext.age 這樣單獨新增,一種是 ext{} 新增多個。

ext.age = 12
ext{
	phone = 123456
	address = 'beijing'
}
task exCustomProperty{	
	println phone
	println address
	println age
}
複製程式碼

相信大家在 AS 中都用過吧,所以這個自定義屬性還是用的很廣泛的。跨 Project、跨 Task 等統一配置相信大家基本都搞過,沒有搞過的就去搞搞。

還有一個地方挺經常用的,那就是 SourceSet,以及 使用 projectFlavors 中,都會和它打交道。

apply plugin:"java"
task exCustomProperty{
sourceSets.each{
	println " ${it.name}--${it.java.srcDirs}"
}
}

sourceSets.all{
	ext.srcDirs = null
}
 sourceSets {
        main { 
            srcDirs = ['main/src']            
        }
        test{
            srcDirs = ['test/src']
        }
 }
複製程式碼

不得不學之「 Gradle」 ③ 構建指令碼基礎

所以我們再開發中的時候,為了避免各個 module 的配置不同和免去手抖帶來的 bug,所以需要統一管理一些配置資訊,所以就可以 ext{},美滋滋,偷懶的利器。

8、指令碼即程式碼,程式碼即指令碼

這就是在 Gradle 中靈活的地方,在這個指令碼檔案中可以使用 Groovy、Java 以及 Gradle 的任何語法和 API,來做我們想要做的事情。在指令碼里,可以定義類,內部類,匯入包,定義方法,常量,介面,靈活的你想象不到,比如 我們根據時間來生成 apk 包名。

def buildTime(){
    def data = new Date()
    def formattedData = date.format('yyyyMMdd')
    return formattedData
}
複製程式碼

劃重點: 本文是完全參考 《Android Gradle 權威指南》而寫,作為學習筆記使用。

相關文章