概覽
Gradle
2013年5月,谷歌發佈Android Studio(基於JetBrains的IntelliJ IDEA),並對Gradle進行了支持。Gradle構建腳本的書寫沒有基於傳統的XML文件,而是基於Groovy
的領域專用語言(DSL
)。
- Gradle構建Android項目時,需要創建一個構建腳本,通常稱爲
build.gradle
。 - Gradle有約定優於配置的原則,即爲設置和屬性提供默認值。
You can specify the Gradle version in either the File > Project Structure > Project menu in Android Studio, or by editing the Gradle distribution reference in the gradle/wrapper/gradle-wrapper.properties file.
...
distributionUrl = https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
...
Groovy
Groovy
Groovy是一種適用於Java虛擬機的動態語言。
類和成員變量
def:聲名變量
方法
在Groovy中,方法的最後一行通常默認返回,即使沒有使用return關鍵字。
Closures
Closures是匿名代碼塊,可以接受參數和返回值。
集合
List和Map
List list = [1, 2, 3, 4]
list.each() { element ->
println element
}
Map prices = [apple:10, car:100]
apply plugin: 'com.android.application'
// apply()是Project類的一個方法。參數是key爲plugin,value爲com.android.application的Map。
project.apply([plugin: 'com.android.application'])
項目和任務
每一次構建都包括至少一個項目,每一個項目又包括一個或多個任務。每個build.gradle文件都代表着一個項目,任務定義在構建腳本里。當初始化構建過程時,Gradle會基於build文件組裝項目和任務對象。一個任務對象包含一系列動作對象,這些動作對象之後會按順序執行。一個單獨的動作對象就是一個待執行的代碼塊,它和Java中的方法類似。
構建生命週期
- 初始化
- 配置
- 執行
Gradle Wrapper
項目根目錄,在terminal上運行gradlew -v
或在命令行上運行gradlew.bat -v
檢查項目中的Gradle Wrapper是否可用。
https://gradle.org/releases/
gradle文件
settings.gradle
:位於項目的根目錄
include ':app'
build.gradle
:頂級構建文件,位於項目的根目錄
buildscript {
repositories {
jcenter()
}
dependencies {
// Gradle的Android插件
classpath 'com.android.tools.build:gradle:2.3.0'
}
}
allprojects {
repositories {
jcenter()
google()
}
}
build.gradle
:模塊級構建文件,位於Module的根目錄,可以覆蓋頂層build.gradle中的任何屬性。
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "com.test"
minSdkVersion 14
targetSdkVersion 27
versionCode 1
versionName "1.0.0"
}
signingConfigs {
debug {
storeFile file("./doc/debug/debug.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
}
buildTypes {
debug {
minifyEnabled false
signingConfig signingConfigs.debug
}
release {
minifyEnabled true
signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
}
**applicationId:**定義在manifest文件中的package,繼續用在你的源代碼和R類中,而之前被用作設備和Google Play唯一標識的package name,現在則被稱之爲applicationId。
ext:
Gradle允許在Project對象上添加額外屬性。這意味着任何build.gradle文件都能定義額外的屬性,添加額外屬性需要通過ext代碼塊。
頂層構建文件添加如下代碼塊:
ext {
compileSdkVersion = 23
buildToolsVersion = '23.0.3'
}
模塊層的構建文件使用rootProject獲取屬性:
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
}
BuildConfig
SDK工具版本升級到17之後,構建工具都會生成一個叫作BuildConfig的類,該類包含一個按照構建類型設置值得DEBUG常量。
android {
buildTypes {
debug {
buildConfigField "boolean","IS_LOG","true"
buildConfigField "String","URL","\"http://test.example.com\""
}
release {
buildConfigField "boolean","IS_LOG","false"
}
}
}
字符串值必須用轉義雙引號括起來,這樣纔會生成實際意義上的字符串。Java代碼中可以這樣用BuildConfig.IS_LOG和BuildConfig.URL
- buildConfigField
- resValue
依賴管理
本地依賴
https://developer.android.google.cn/studio/build/dependencies.html
dependencies {
// 依賴單個JAR文件
compile files('libs/test.jar')
// 依賴所有文件
compile fileTree('libs')
// 依賴指定文件格式,如JAR
compile fileTree(dir: 'libs', include: ['*.jar'])
// 遠程依賴
implementation 'com.example.android:app-magic:12.3'
// 本地庫模塊依賴項
implementation project(':mylibrary')
}
**原生依賴庫.so文件:**在模塊的main目錄下新建jniLibs文件夾,然後爲每個平臺(armeabi、mips、x86)創建子文件夾。如果此約定不生效,可以在構建文件中設置相關設置:
android {
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
}
}
.aar文件:
- 添加依賴倉庫文件夾
- 添加依賴,如下
dependencies {
compile(name: 'aarName', ext: 'aar')
}
語義化版本
將依賴添加到JCenter等依賴倉庫時,約定遵循了一套版本化規則,稱爲語義化版本。版本數字的格式一般爲major.minor.patch
- 當做不兼容的API變化時,major版本增加。
- 當以向後兼容的方式添加功能時,minor版本增加。
- 當修復一些bug時,patch版本增加。
基於以上規則,可以添加動態化版本。+
遠程倉庫
如果您的依賴項並非本地庫或文件樹,Gradle會在您的build.gradle文件repositories程序塊中指定的任何一個在線代碼庫中尋找文件。列出各代碼庫的順序決定了Gradle在這些代碼庫中搜索各項目依賴項的順序。
默認情況下,Android Studio新項目會在項目的頂級build.gradle文件中指定Google的Maven代碼庫和 JCenter作爲代碼庫位置,如下所示:
allprojects {
repositories {
google()
jcenter()
}
}
如果您需要的內容來自Maven中央代碼庫,則添加**mavenCentral()**如果來自本地代碼庫,則使用 mavenLocal()
allprojects {
repositories {
google()
jcenter()
mavenCentral()
mavenLocal()
}
}
或者,也可像下面這樣聲明特定Maven或Ivy代碼庫:
allprojects {
repositories {
maven {
url "https://repo.example.com/maven2"
}
maven {
url "file://local/repo/"
}
ivy {
url "https://repo.example.com/ivy"
}
}
}
本地倉庫
通過使用flatDirs添加一個常用文件夾作爲倉庫。
repositories {
flatDir {
dirs 'libs', '../Framework/libs'
}
}
構建variant
https://developer.android.google.cn/studio/build/build-variants.html
構建類型
https://developer.android.google.cn/studio/build/build-variants.html#build-types
android {
buildTypes {
debug {
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
// 用已有的構建類型屬性初始化新的構建類型
staging.initWith(buildTypes.debug)
staging {
applicationIdSuffix ".staging"
versionNameSuffix "-staging"
}
}
}
可以根據構建類型來添加依賴。如debugCompile ‘com.android.support:***:1.0.0’
product flavor
https://developer.android.google.cn/studio/build/build-variants.html#product-flavors
android {
productFlavors {
free {
}
paid {
}
}
}
簽名配置
android {
signingConfigs {
staging.initWith(signingConfigs.debug)
release {
storeFile file("../key/debug.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
}
}
加速構建
Jack和Jill
Jack(Java Android Compiler Kit)是一個新的Android構建工具鏈,其可以直接編譯Java源碼爲Android Dalvik的可執行格式。它有自己的.jack依賴庫格式,也採用了打包和縮減。
Jill(Jack Intermediate Library Linker)是一個可以將.aar和.jar文件轉換成.jack依賴庫的工具。
useJack = true