文章是翻譯整理的官網(wǎng)文檔developer.android/studio/build/
一、Gradle和Gradle插件
-
Gradle:Gradle是一款幫助開發(fā)人員更快更好的編譯、自動(dòng)化運(yùn)行和分發(fā)軟件的工具。Gradle具有無與倫比的通用性,可以編譯Java、C++,Python或者任何其他你使用的語言。Gradle官網(wǎng)鏈接。Android Studio創(chuàng)建的APP工程中可以在
gradle/wrapper/gradle-wrapper.properties文件里配置gradle的版本,如下:
...
distributionUrl = https\://services.gradle.org/distributions/gradle-4.4-all.zip
...
-
Gradle插件:編譯Android App的插件叫做Android Plugin for Gradle。 Android Studio的編譯系統(tǒng)使用的就是Gradle,Android Plugin for Gradle增加了編譯Android APP所需要的特性。 gradle-plugin安卓開發(fā)者官網(wǎng) 雖然這個(gè)插件一般都是和Android Studio同步更新,但是它可以獨(dú)立于Android Studio單獨(dú)運(yùn)行和更新。Android Studio創(chuàng)建的APP工程中可以在頂層的
build.gradle文件buildscript里配置依賴的插件版本。如下:
buildscript {
repositories {
// Gradle 4.1開始可以通過google()方法來支持Google的Maven倉庫。
// 我們需要從這個(gè)倉庫下載Android plugin 3.0.0或者更新的版本。
google()
...
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.0'
}
}
不同版本的插件所需要的gradle版本也不一樣,對應(yīng)關(guān)系如下:

一般當(dāng)升級Android Studio的時(shí)候會(huì)收到升級gradle插件到最新版本的提醒,我們可以直接接受建議升級版本,也可以使用原來工程的配置。不過為了最佳的性能,建議升級到最新的版本。
二、 構(gòu)建Android APP的配置文件
自定義構(gòu)建配置需要對一個(gè)或多個(gè)構(gòu)建配置文件進(jìn)行更改。這些純文本文件使用域特定語言 (DSL) 以 Groovy 語言描述和操作構(gòu)建邏輯,Groovy是一種適用于 Java 虛擬機(jī) (JVM) 的動(dòng)態(tài)語言。因?yàn)?Android Plugin for Gradle 引入了需要的大多數(shù) DSL 元素,所以無需了解 Groovy 便可開始配置構(gòu)建。如需了解有關(guān) Android 插件 DSL 的更多信息,請閱讀 DSL 參考文檔。
開始新項(xiàng)目時(shí),Android Studio 會(huì)自動(dòng)為我們創(chuàng)建其中的部分文件,并為它們填充合理的默認(rèn)值。

Android 應(yīng)用標(biāo)準(zhǔn)項(xiàng)目結(jié)構(gòu)中包括的 Gradle 構(gòu)建配置文件有,Gradle設(shè)置文件(settings.gradle)、Gradle構(gòu)建文件(頂級和模塊級build.gradle文件)、Gradle屬性文件(gradle.properties和local.properties)。想要自定義構(gòu)建配置,必須了解其中每一個(gè)文件的范圍和用途及其應(yīng)定義的基本 DSL 元素。下面我們就一個(gè)一個(gè)的看。
1. Gradle 設(shè)置文件
settings.gradle 文件位于項(xiàng)目根目錄,用于指示 Gradle 在構(gòu)建應(yīng)用時(shí)應(yīng)將哪些模塊包括在內(nèi)。對大多數(shù)項(xiàng)目而言,該文件很簡單,只包括以下內(nèi)容:
include ‘:app’
不過,多模塊項(xiàng)目需要指定應(yīng)包括在最終構(gòu)建之中的每個(gè)模塊。
2. Gradle 構(gòu)建文件
2.1 頂級構(gòu)建文件
頂級 build.gradle 文件位于項(xiàng)目根目錄,用于定義適用于項(xiàng)目中所有模塊的構(gòu)建配置。默認(rèn)情況下,這個(gè)頂級構(gòu)建文件使用 buildscript {} 代碼塊來定義項(xiàng)目中所有模塊共用的 Gradle 存儲(chǔ)區(qū)和依賴項(xiàng)。以下代碼示例描述的默認(rèn)設(shè)置和 DSL 元素。
/**
* buildscript {} 是配置構(gòu)建工具Gradle本身所需要的依賴和倉庫的代碼區(qū)塊,
* 也就是說不能把APP模塊所需要的依賴放到這里。
* 如:這個(gè)區(qū)塊里包含gradle-plugin的依賴,因?yàn)檫@個(gè)插件包含了Gradle構(gòu)建APP模塊所需要的附加命令。
*/
buildscript {
/**
* repositories {} 區(qū)域配置Gradle用來下載依賴的倉庫地址。
* Gradle內(nèi)置支持的遠(yuǎn)程倉庫有JCenter、Maven Central 和 Ivy,4.1版本開始內(nèi)置支持google()。
* 也可以使用本地倉庫或者配置我們自己的遠(yuǎn)程倉庫地址。
* 下面代碼示例Gradle使用JCenter作為查找依賴庫的代碼倉庫。
*/
repositories {
jcenter()
}
/**
* dependencies {} 區(qū)域配置了Gradle編譯APP工程所需要的依賴。
* 下面代碼展示路徑依賴3.1.0版本gradle-plugin
*/
dependencies {
classpath 'com.android.tools.build:gradle:3.1.0'
}
}
/**
* allprojects {} 區(qū)域可以配置工程中所有模塊都是到的代碼倉庫和依賴,如,三方插件或者庫。
* 如果依賴不是被所有模塊都需要,那應(yīng)該將依賴配到需要它的模塊級的build.gradle文件中。
* 在Android Studio新建的工程里,頂級的build.gradle中只配置JCenter為所有模塊的默認(rèn)倉庫,但不配置任何依賴。
*/
allprojects {
repositories {
jcenter()
}
}
2.2 模塊級構(gòu)建文件
模塊級 build.gradle 文件位于每個(gè) <project>/<module>/ 目錄,用于配置適用于其所在模塊的構(gòu)建設(shè)置。通過配置這些構(gòu)建設(shè)置來提供自定義打包選項(xiàng)(例如附加構(gòu)建類型和產(chǎn)品風(fēng)味),以及替換 main/ 應(yīng)用清單或頂級 build.gradle 文件中的設(shè)置。
以下這個(gè)示例 Android 應(yīng)用模塊 build.gradle 文件概述了應(yīng)該了解的部分基本 DSL 元素和設(shè)置。
/**
* 編譯配置第一句話意思是在構(gòu)建工程中引入Android plugin for Gradle
* 這樣我們才可以在android {}代碼塊中使用構(gòu)建Android APP所需的特定編譯選項(xiàng)。
*/
apply plugin: 'com.android.application'
/**
* android {} 中配置構(gòu)建Android APP所需的特定編譯選項(xiàng)。
*/
android {
/**
* compileSdkVersion:指定Gradle編譯APP時(shí)所使用的Android API的版本。
* 這意味著我們的APP只能使用該版本及其以下版本中的API。
*
* buildToolsVersion:指定Gradle編譯APP時(shí)所使用的SDK編譯工具、命令行工具和編譯器的版本。
* 我們需要通過SDK Manager去下載使用到的編譯工具。
*/
compileSdkVersion 26
buildToolsVersion "27.0.3"
/**
* defaultConfig{}默認(rèn)配置和配置編譯變體的入口,
* 還可以在這里動(dòng)態(tài)的覆蓋main/AndroidManifest.xml的屬性。
* 在這個(gè)區(qū)塊還可以設(shè)置產(chǎn)品風(fēng)味,給不同的風(fēng)味版本配置不同的屬性值。
*/
defaultConfig {
/**
* applicationId APP發(fā)布安裝時(shí)的唯一標(biāo)識.
* 但是在代碼中引用的包名依然是在main/AndroidManifest.xml文件中屬性package設(shè)置的名稱。
*/
applicationId 'com.example.myapp'
// 定義APP需要支持的 Android API 最小的版本。
minSdkVersion 15
// 指定用來測試APP的 Android API 版本
targetSdkVersion 26
// 定義APP的版本
versionCode 1
// 定義APP的版本名
versionName "1.0"
}
/**
* buildTypes {} 區(qū)塊中配置多個(gè)編譯類型。編譯系統(tǒng)默認(rèn)定義了兩個(gè)類型:debug and release.。
* debug類型:默認(rèn)的配置文件中沒有展示出來,它包含了debug工具,使用debug key簽名APK。
* release類型:使用Proguard設(shè)置,默認(rèn)不簽名APK。
*/
buildTypes {
/**
* Android Studio默認(rèn)配置release編譯類型開啟代碼縮減和指定代碼混淆文件。
*/
release {
minifyEnabled true // 開啟代碼縮減
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
/**
* productFlavors {} 區(qū)域可以配置不同的產(chǎn)品風(fēng)味。
* 這里不同風(fēng)味版本的配置可以覆蓋掉 defaultConfig {} 中的設(shè)置。
* 產(chǎn)品風(fēng)味是可選項(xiàng),編譯系統(tǒng)默認(rèn)不會(huì)自動(dòng)創(chuàng)建不同的產(chǎn)品風(fēng)味。
* 下面例子創(chuàng)建了免費(fèi)版和付費(fèi)版兩種產(chǎn)品風(fēng)味。
* 每種產(chǎn)品風(fēng)味都指定了自己的應(yīng)用ID,這使得兩種風(fēng)味的版本可以同時(shí)安裝在一個(gè)設(shè)備上。
*/
productFlavors {
free {
applicationId 'com.example.myapp.free'
}
paid {
applicationId 'com.example.myapp.paid'
}
}
/**
* splits {} 配置可以針對不同的屏幕密度和不同ABI架構(gòu)的設(shè)備編譯不同的APP
*/
splits {
// APP分割機(jī)制針對屏幕密度的設(shè)置
density {
// 打開或關(guān)閉密度分割機(jī)制
enable false
// 分割A(yù)PP不支持如下屏幕密度設(shè)備
exclude "ldpi", "tvdpi", "xxxhdpi", "400dpi", "560dpi"
}
abi {
enable true
// 清除默認(rèn)配置
reset()
// 分割A(yù)PP支持如下ABI設(shè)備
include "armeabi-v7a", "armeabi-v8a"
}
}
}
/**
* dependencies {} 代碼塊中指定本模塊中所需要的依賴
*/
dependencies {
compile project(":lib")
compile 'com.android.support:appcompat-v7:27.1.1'
compile fileTree(dir: 'libs', include: ['*.jar'])
}
3. Gradle 屬性文件
Gradle 還包括兩個(gè)屬性文件,位于項(xiàng)目根目錄,可用于指定適用于 Gradle 構(gòu)建工具包本身的設(shè)置:
3.1 gradle.properties
我們可以在其中配置項(xiàng)目范圍的 Gradle 設(shè)置,例如 Gradle 后臺(tái)進(jìn)程的最大堆大小。如需了解詳細(xì)信息,請參閱構(gòu)建環(huán)境。
# Project-wide Gradle settings.
org.gradle.jvmargs=-Xmx2536M
android.useDeprecatedNdk=true
3.2 local.properties
為構(gòu)建系統(tǒng)配置本地環(huán)境屬性,例如 SDK 安裝路徑。由于該文件的內(nèi)容由 Android Studio 自動(dòng)生成并且專用于本地開發(fā)者環(huán)境,因此我們不應(yīng)該手動(dòng)修改該文件,不應(yīng)該將其納入到版本控制系統(tǒng)中。
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
#Thu Sep 28 20:26:40 CST 2017
ndk.dir=/Users/name/Library/Android/sdk/ndk-bundle
sdk.dir=/Users/name/Library/Android/sdk
三、構(gòu)建Android APP的流程

如圖所示,典型 Android 應(yīng)用模塊的構(gòu)建流程通常依循下列步驟:
- 編譯器將您的源代碼轉(zhuǎn)換成 DEX(Dalvik Executable) 文件(其中包括運(yùn)行在 Android 設(shè)備上的字節(jié)碼),將所有其他內(nèi)容轉(zhuǎn)換成已編譯資源。
- APK 打包器將 DEX 文件和已編譯資源合并成單個(gè) APK。不過,必須先簽署 APK,才能將應(yīng)用安裝并部署到 Android 設(shè)備上。
- APK 打包器使用調(diào)試或發(fā)布密鑰庫簽署您的 APK:
- 如果您構(gòu)建的是調(diào)試版本的應(yīng)用(即專用于測試和分析的應(yīng)用),打包器會(huì)使用調(diào)試密鑰庫簽署您的應(yīng)用。Android Studio 自動(dòng)使用調(diào)試密鑰庫配置新項(xiàng)目。
- 如果您構(gòu)建的是打算向外發(fā)布的發(fā)布版本應(yīng)用,打包器會(huì)使用發(fā)布密鑰庫簽署您的應(yīng)用。要?jiǎng)?chuàng)建發(fā)布密鑰庫,請閱讀在 Android Studio 中簽署您的應(yīng)用。
- 在生成最終 APK 之前,打包器會(huì)使用 zipalign 工具對應(yīng)用進(jìn)行優(yōu)化,減少其在設(shè)備上運(yùn)行時(shí)的內(nèi)存占用。