原文地址:https://developer.android.com/studio/build/index.html
譯文作者:Shane
Android構(gòu)建系統(tǒng)編譯app資源和源碼文件拼窥,然后將它們打包進你可以測試,部署鲁纠,簽名和分發(fā)的APK。Android Studio使用Gradle(一個高級構(gòu)建工具)來自動化管理構(gòu)建過程情龄,允許你定義靈活的構(gòu)建配置捍壤。每個構(gòu)建配置可以定義自己所屬的代碼和資源,當(dāng)重用所有app版本公有的那部分的時候鹃觉。Gradle的Android插件(Android Plugin for Gradle)和Gradle一起協(xié)同工作,提供處理和具體構(gòu)建以及測試Android應(yīng)用相關(guān)的配置設(shè)置祷肯。
Gradle及其Android插件獨立于Android Studio運行疗隶。這意味著,你可以通過Android Studio允青,從自己機器上的命令行卵沉,或者是從別的沒有安裝Android Studio的機器上構(gòu)建應(yīng)用。如果你沒有使用Android Studio史汗,你可以學(xué)習(xí) 從命令行構(gòu)建和運行你的app。構(gòu)建的輸出都是一樣的瓷蛙,無論你是通過命令行構(gòu)建戈毒,還是從遠程機器,或者是使用Android Studio構(gòu)建埋市。
注意:因為Gradle及其Android插件獨立于Android Studio運行,你需要單獨更新構(gòu)建工具食听。閱讀發(fā)布摘要來學(xué)習(xí)如何 更新Gradle及其Android插件.
Android構(gòu)建系統(tǒng)的靈活性是你能夠?qū)崿F(xiàn)自定義構(gòu)建配置文件而無需修改你的app的核心源碼。這一節(jié)幫助你理解Android構(gòu)建系統(tǒng)如何工作樱报,以及如何幫助你定制以及自動化多個構(gòu)建配置。如果你僅僅想要學(xué)習(xí)更多關(guān)于部署你的app民珍,參見Building and Running from Android Studio盗飒。立即開始使用Android Studio創(chuàng)建自定義構(gòu)建配置,參見Configuring Build Variants.
構(gòu)建過程 The Build Process
構(gòu)建過程包括許多工具津肛,以及將工程轉(zhuǎn)換為APK的過程。構(gòu)建過程很靈活身坐,因此理解一些內(nèi)部流程將會非常有用落包。
一個典型的App模塊構(gòu)建過程,如圖1所示涯鲁,跟隨這些通用步驟:
- 編譯器將你的源碼轉(zhuǎn)換到DEX文件中有序,其中包括Android設(shè)備上運行的字節(jié)碼,和其他一切編譯后的資源旭寿。
- APK打包器將DEX文件和編譯后的資源一起打包到一個單獨的APK。然而肩祥,在你的app能被安裝和部署到Android設(shè)備上之前缩膝,APK還需要執(zhí)行簽名。
- APK打包器使用debug或者release版本的密鑰庫(keystore)對你的APK進行簽名:
a. 如果你準(zhǔn)備構(gòu)建一個debug版本的app将饺,也就是僅用于測試和分析的版本,打包器會使用debug keystore對APK進行簽名贸桶。Android Studio會自動為每個新的工程配置debug keystore舅逸。
b. 如果你準(zhǔn)備構(gòu)建一個打算對外發(fā)布的release版本的app桌肴,打包器會使用release keystore對你的app進行簽名坠七。要創(chuàng)建一個release keystore,參見Signing your app in Android Studio彪置。 - 在生成最終的APK之前蝇恶,打包器使用zipalign 工具對你的app進行優(yōu)化,使得運行時使用更少內(nèi)存潘懊。
在構(gòu)建過程最后贿衍,你要么得到一個debug版本的APK要么得到一個release版本的APK,可用于部署贸辈,測試,或者對外發(fā)布奢啥。
定制構(gòu)建配置 Custom Build Configurations
Gradle及其插件幫助你配置以下幾個構(gòu)建方面:
-
構(gòu)建類型 Build Type
構(gòu)建類型定義了構(gòu)建和打包過程Gradle使用的幾個屬性嘴拢,通常需要為開發(fā)生命周期的不同階段定義配置屬性。比如炊汤,debug構(gòu)建類型開啟debug選項,使用debug key簽名APK姑曙,而release構(gòu)建類型可能會壓縮迈倍、混淆APK,并且用一個用于發(fā)布的release key簽名APK宴合。為了構(gòu)建你的app,你必須定義至少一個構(gòu)建類型——Android Studio默認創(chuàng)建debug和release構(gòu)建類型卦洽。開始為你的app定制打包設(shè)置,學(xué)習(xí)如何Configure build types该窗。 -
產(chǎn)品喜好 Product Flavors
Product Flavors表示你可能發(fā)布給用戶的不同版本的app,比如免費版和付費版酗失。你可以定制Product Flavors來使用不同的代碼和資源昧绣,而重用那些所有版本公有的部分。Product Flavors是可選的拖刃,你必須手動創(chuàng)建斩启。開始創(chuàng)建不同版本的app,學(xué)習(xí)如何Configure product flavors兔簇。 -
構(gòu)建變種 Build Variants
構(gòu)建類型(Build Type)和產(chǎn)品喜好(Product Flavors)結(jié)合起來就是一個構(gòu)建變種(Build Variant)。構(gòu)建變種代表了Gradle使用的構(gòu)建你的app的配置文件边酒。盡管你不能直接配置構(gòu)建變種狸窘,你可以通過配置構(gòu)建類型和產(chǎn)品喜好來打造一個變種。學(xué)習(xí)如何創(chuàng)建和管理構(gòu)建變種氓涣,閱讀 Configure build variants 陋气。 -
清單條目 Manifest Entries
你可以在構(gòu)建變種的配置中指明AndroidManifest.xml中定義的一些屬性。這些配置項將會重寫存在于AndroidManifest.xml中的存在項巩趁。如果你想針對你的app生成多個APK,每個APK有不同的應(yīng)用程序名蠢古,最小SDK版本或者是目標(biāo)SDK版本,這時候就會很有用草讶。當(dāng)多個清單文件存在時,Gradle將會 合并清單設(shè)置. -
依賴管理 Dependencies
構(gòu)建系統(tǒng)管理本地和遠程倉庫的工程依賴脊框〖模可以讓你免于手動搜索沉御、下載,然后將二進制依賴包拷貝到工程目錄這個過程伐谈。查看更多信息,學(xué)習(xí)如何聲明依賴诵棵。 -
簽名 Signing
你可以在構(gòu)建配置中指明簽名相關(guān)設(shè)置祝旷,在構(gòu)建過程中將會自動為你的APK簽名。構(gòu)建系統(tǒng)用默認密鑰和已知憑據(jù)的默認證書簽名debug版本距贷,避免在構(gòu)建時候提示輸入密碼吻谋。構(gòu)建系統(tǒng)不會簽名release版本,除非你顯式定義一個簽名配置漓拾。如果你還沒有一個release密鑰,你可以按照《Signing your applications》描述的方法生成一個速种。 -
ProGuard
構(gòu)建系統(tǒng)允許為每個構(gòu)建變種指明一個不同的ProGuard 規(guī)則文件脯颜。在構(gòu)建過程中,構(gòu)建系統(tǒng)運行ProGuard來壓縮和混淆類文件闸餐。
構(gòu)建配置文件 Build Configuration Files
創(chuàng)建自定義的構(gòu)建配置需要你更改一個或多個構(gòu)建配置文件,或者build.gradle文件近上。這些純文本文件使用領(lǐng)域特定語言(DSL)聲明和操控構(gòu)建邏輯。在這里的DSL指的是Groovy壹无,一種基于JVM的動態(tài)語言感帅。你不需要知道Groovy就可以開始配置構(gòu)建,因為Gradle的Android插件引入了你需要的大部分DSL元素失球。學(xué)習(xí)更多關(guān)于Android Plugin DLS,閱讀 DSL reference documentation豺撑。
當(dāng)開始一個新工程時黔牵,Android Studio自動為你創(chuàng)建了一些文件,如圖2所示陆错,并且基于合理的默認值做了一些修改跃巡。
對于一個Android應(yīng)用來說,這里有一些Gradle構(gòu)建配置文件是標(biāo)準(zhǔn)工程結(jié)構(gòu)的一部分素邪。在開始配置之前,理解這些文件的使用范圍和目的偷线,以及它們定義基本的DSL元素是非常重要的沽甥。
Gradle設(shè)置文件
位于工程根目錄下的gradle.setting
文件,告訴Gradle當(dāng)構(gòu)建app的時候需要包含哪些模塊摆舟。對大多數(shù)工程來說邓了,這個文件比較簡單骗炉,僅僅包含下面的:
include ':app'
然而蛇受,對于包含多個模塊的工程,需要指明放到最終build里面的每個模塊兢仰。
頂層build文件
頂層build文件是位于工程根目錄下的build.gradle
文件,定義了對于工程所有Module都有效的構(gòu)建配置文件轻专。默認秸弛,頂層build文件使用buildScript {}
塊來定義Gradle倉庫以及對于工程所有Module都通用的依賴。下面樣例代碼描述了默認設(shè)置递览,以及你可以在一個新創(chuàng)建的工程的頂層build文件中找到的DSL元素绞铃。
/**
* buildscript { } 配置塊是配置Gradle倉庫以及Gradle本身依賴的地方嫂侍。
* 也就意味著,你不應(yīng)該把自己的模塊依賴放到這個位置挑宠。比如,這個配置
* 塊包含了Gradle的Android插件作為一個依賴懒鉴,因為它提供了Gradle需
* 要的額外的指令來構(gòu)建Android應(yīng)用模塊碎浇。
*/
buildscript {
/**
* repositories { } 配置塊配置了Gradle使用的用來搜索和下載依賴的倉
* 庫。Gradle預(yù)配置支持遠程倉庫奴璃,比如JCenter,Maven Central還有
* Ivy抄课。你也可以使用本地倉庫或者定義自己的遠程倉庫。下面的代碼
* 定義JCenter作為Gradle用來查找依賴的倉庫
*/
repositories {
jcenter()
}
/**
* dependencies { } 配置塊 定義了Gradle用來構(gòu)建工程所需的依賴條件跟磨。
* 下面這一行,添加Gradle的Android插件v2.0.0作為一個classpath依賴甸饱。
*
*/
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0'
}
}
/**
* allprojects { } 配置塊 是配置你的工程中所有模塊都使用的倉庫和依賴
* 的地方仑濒,比如第三方插件或者庫。不被所有模塊都共用的依賴應(yīng)該配置
* 在模塊級別的build.gradle文件中墩瞳。對于新建的工程,Android Studio
* 配置JCenter作為默認倉庫热凹,但不會配置任何依賴泪电。
*/
allprojects {
repositories {
jcenter()
}
}
模塊級別的Build文件
模塊級別的build.gradle
文件位于每個<工程>/<模塊>目錄下,可以讓你為每個模塊單獨配置build設(shè)置項碟渺。配置項允許你提供自定義打包選項突诬,比如額外的構(gòu)建類型(build type)和產(chǎn)品喜好(product flavor),以及重寫在main/
目錄下的應(yīng)用manifest清單或者是頂層build.gradle
文件旺隙。
下面這個app模塊build.gradle
文件樣例總結(jié)了一些你應(yīng)該知道的基本DSL元素和設(shè)置。
/**
* 在這個配置文件的第一行垄提,將Gradle的Android插件應(yīng)用到這個構(gòu)建中抠刺。
* 使得后面的android配置塊可用來指明android相關(guān)的構(gòu)建選項。
*/
apply plugin: 'com.android.application'
android {
/**
* compileSdkVersion指明Gradle準(zhǔn)備使用的Android API等級來編譯app高蜂。
* 這意味著你的app可以使用包含在這個API等級及以下的API特性罕容。
*
* buildToolsVersion 指明了Gradel將會使用的SDK build工具稿饰,命令行工具
* 編譯器的版本露泊。你應(yīng)用使用SDK Manager來下載build工具。
*/
compileSdkVersion 23
buildToolsVersion "23.0.3"
/**
* defaultConfig { } 配置塊封裝了所有build變種都會使用到的默認設(shè)置和
* 入口信息侣姆, 并且可以從構(gòu)建系統(tǒng)中動態(tài)重寫main/AnroidManifest.xml中的一些屬性。
* 你可以配置product flavors來重寫這些值捺宗,基于不同版本的app。
*/
defaultConfig {
/***
* applicationId唯一標(biāo)識發(fā)布的包蚜厉。
* 但是畜眨,你的源碼應(yīng)該仍然引用定義在main/AndroidManifest.xml文件
* 中的包屬性。
*/
applicationId 'com.example.myapp'
// 定義用來運行app的最小API等級
minSdkVersion 14
// 指明用來測試app的API等級
targetSdkVersion 23
// 定義你的app版本號
versionCode 1
// 定義一個友好的版本名
versionName "1.0"
}
/**
* buildTypes { } 配置塊是你可以配置多個build types的地方贰健。
* 默認早抠,構(gòu)建系統(tǒng)定義兩個build types: debug和release。
* debug build type 不會顯式的展現(xiàn)在默認構(gòu)建配置中,但是它
* 包含了調(diào)試工具游昼,并且用debug密鑰進行簽名。release build type
* 應(yīng)用Proguard(混淆)設(shè)置烘豌,并且不會簽名默認密鑰。
*/
buildTypes {
/**
* 默認囚聚,Android Studio 配置release build type 使用minifyEnabled來開啟代碼壓縮标锄,并且還會指明Proguard設(shè)置文件。
*/
release {
minifyEnabled true // 為release build type開啟代碼壓縮
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
/**
* productFlavors { } 配置塊是你可以配置多個product flavors的地方谓松。
* 這樣你可以讓你創(chuàng)建不同版本的app星压,通過重寫defaultConfig {}設(shè)置項娜膘。
* Product flavors是可選的优质,構(gòu)建系統(tǒng)默認不會創(chuàng)建他們。這個例子
* 創(chuàng)建了一個免費版和付費版的product flavor演怎。每個product flavor指明
* 自己的application ID,以便于它們可以共存于Google Play Store或同一個Android設(shè)備中颤枪。
*/
productFlavors {
free {
applicationId 'com.example.myapp.free'
}
paid {
applicationId 'com.example.myapp.paid'
}
}
}
/**
* dependencies { } 配置塊位于模塊build配置文件的頂層畏纲。
* 僅僅指明需要build模塊本身的一些依賴條件。
*/
dependencies {
compile project(":lib")
compile 'com.android.support:appcompat-v7:22.0.1'
compile fileTree(dir: 'libs', include: ['*.jar'])
}
Gradle屬性文件
Gradle也包含兩個屬性文件盗胀,位于工程根目錄锄贼,用來指明Gradle構(gòu)建工具箱自身的一些設(shè)置。
gradle.properties
??這是配置工程范圍內(nèi)的Gradle設(shè)置的地方宅荤,比如Gradle daemon的最大堆大小。更多信息惹盼,請查看Configuring the build environment惫确。
local.properties
??為構(gòu)建系統(tǒng)配置本地環(huán)境屬性,比如SDK安裝路徑改化。因為這個文件內(nèi)容是由Android Studio自動生成,并且與本地開發(fā)者環(huán)境相關(guān)揍鸟,你最好不要手動修改這個文件燥爷,或者從你的版本控制系統(tǒng)中check出來懦窘。
同步工程和Gradle文件(Syncigng Project with Gradle Files)
當(dāng)你改變了工程中的構(gòu)建配置文件后稚配,Android Studio會要求你同步工程文件,以便于它能夠?qū)肽阈薷牡呐渲眯畔⒌来ǎ缓筮\行一些檢查來確保你的配置不會創(chuàng)建構(gòu)建錯誤。
要同步工程文件臊岸,點擊當(dāng)你改變配置文件后會出現(xiàn)在通知欄上的Sync Now
尊流,或者點擊菜單欄上的Sync Project
。如果Android Studio通知了任何配置錯誤崖技,比如,你的源碼使用的API特性僅僅在比你的compiledSdkVersion
更高的API版本才可用瞎访,Message
窗口將會出現(xiàn)描述這個問題。
源集(Source Sets)
Android Studio會為每個模塊將源代碼和資源文件組成一個邏輯上的源集扒秸。每個模塊的main/ 源集包括所有構(gòu)建變種都使用的源碼和資源伴奥。其他的源集目錄是可選的,Android Studio不會自動為你創(chuàng)建他們當(dāng)你配置新的構(gòu)建變種的時候翼闽。但是渔伯,構(gòu)建具體的app版本的時候,創(chuàng)建與main/類似的源集肄程,可以幫助組織Gradle應(yīng)該使用的文件和資源。
src/main/
??包括所有構(gòu)建變種都通用的代碼和資源的源集选浑。
src/<buildType>/
??創(chuàng)建這個源集來包括僅僅為一個具體的build type使用的代碼和資源蓝厌。
src/<productFlavor>/
??創(chuàng)建這個源集來包括僅僅為一個具體的product flavor使用的代碼和資源。
src/<productFlavorBuildType>/
??創(chuàng)建這個源集來包括僅僅為一個具體的構(gòu)建變種使用的代碼和資源古徒。
比如拓提,生成這個fullDebug
版本的app,構(gòu)建系統(tǒng)合并下面這些源集的代碼和資源:
- src/fullDebug/(構(gòu)建變種源集)
- src/debug/(構(gòu)建類型build type源集)
- src/full/ (product flavor源集)
- src/main/(main源集)
注意:當(dāng)你在Android Studio中創(chuàng)建一個新的文件或者目錄時隧膘,使用File->New菜單項寺惫,你可以為一個具體的源集創(chuàng)建它西雀。你可以選擇的這些源集是基于你的構(gòu)建配置的歉摧,并且Android Studio自動創(chuàng)建需要的目錄叁温,如果它們不存在的話膝但。
如果不同的源集包含同一個文件的不同版本,當(dāng)決定哪個文件使用的時候Gradle使用下面的優(yōu)先級順序莺奸。(在左邊的源集會重寫右邊的源集文件和設(shè)置)憾筏。
build variant > build type > product flavor > main source set > library dependencies
這可以讓Gradle在構(gòu)建的時候使用與具體構(gòu)建變種相關(guān)的文件氧腰,當(dāng)重用activity刨肃,應(yīng)用邏輯真友,以及和其他版本通用的資源的時候盔然。當(dāng)merging multiple manifests的時候,Gradle使用同樣的優(yōu)先級順序挺尾,因此每個構(gòu)建變種可以定義不同的組件或者權(quán)限在最終的manifest文件中遭铺。學(xué)習(xí)更多關(guān)于創(chuàng)建自定義源集甫题,點擊Create source sets for build variants涂召。