Android Gradle 插件中文指南
以下內容由飛雪無情提供翻譯
原文地址 http://tools.android.com/tech-docs/new-build-system/user-guide
目錄
- 1 介紹
- 1.1 新構建系統的目標
- 1.2 Gradle是什么?
- 2 要求
- 3 基礎工程
- 3.1 基本的build文件
- 3.2 工程結構
- 3.2.1 配置結構
- 3.3 構建任務
- 3.3.1 通用任務
- 3.3.2 Java工程任務
- 3.3.3 Android任務
- 3.4 自定義構建
- 3.4.1 Manifest選項
- 3.4.2 構建類型
- 3.4.3 簽名配置
- 3.4.4 使用混淆
- 3.4.5 清理資源
- 4 依賴,Android庫工程以及多工程設置
- 4.1 依賴二進制包
- 4.1.1 本地包
- 4.1.2 遠程artifacts
- 4.2 多工程設置
- 4.3 庫工程
- 4.3.1 創建一個庫工程
- 4.3.2 普通工程和庫工程的區別
- 4.3.3 引用一個庫工程
- 4.3.4 庫工程發布
- 4.1 依賴二進制包
- 5 測試
- 5.1 基本介紹以及配置
- 5.2 運行測試
- 5.3 測試Android庫
- 5.4 測試報告
- 5.4.1 單工程報告
- 5.4.2 多工程報告
- 5.5 Lint支持
- 6 Build Variants(構建變種版本)
- 6.1 Product flavors(產品定制)
- 6.2 Build Type(構建類型) + Product Flavor(產品定制) = Build Variant(構建變種版本)
- 6.3 Product Flavor Configuration(產品定制配置)
- 6.4 Sourcesets and Dependencies(Sourcesets和依賴)
- 6.5 Building and Tasks(構建和任務)
- 6.6 Testing(測試)
- 6.7 Multi-flavor variants(多種定制的版本)
- 7 高級構建定制
- 7.1 構建選項
- 7.1.1 Java編譯選項
- 7.1.2 aapt選項
- 7.1.3 dex選項
- 7.2 操縱任務
- 7.3 BuildType and Product Flavor的屬性參考
- 7.4 使用sourceCompatibility 1.7
- 7.1 構建選項
1 介紹
本文檔適用于Gradle plugin 0.9版本,所以可能和我們1.0之前介紹的老版本有所不同。
1.1 新構建系統的目標
新構建系統的目標是:
- 可以很容易的重用代碼和資源
- 可以很容易的創建應用的衍生版本,所以不管你是創建多個apk,還是不同功能的應用都很方便
- 可以很容易的配置、擴展以及自定義構建過程
- 和IDE無縫整合
1.2 Gradle是什么
Gradle是一個非常優秀的構建系統工具,允許你通過插件的方式創建自定義的構建邏輯
Gradle的以下特性讓我們選擇了它:
- 用過領域專用語言(DSL)描述和控制構建邏輯
- 構建文件基于Groovy,并且可以組合使用各種定義的元素,然后通過代碼來控制這些DSL達到定制邏輯的目的
- 內建的基于Maven或者Ivy的依賴管理
- 使用非常靈活,Gradle不會強制實現的方式,你可以使用最佳實踐
- 插件能提供DSL以及API為構建文件使用
- 良好的工具API以供IDE集成
2 要求
- Gradle 1.10或者1.11或者1.12,并且使用0.11.1版本的插件
- SDK with Build Tools要求19.0.0,有些功能可能需要更新的版本
3 基礎工程
一個Gradle工程是通過名字叫 build.gradle 的文件描述其構建過程的,該文字位于工程的根目錄下。
3.1 基本的build文件
最基本的Java工程,其 build.gradle 非常簡單:
apply plugin: 'java'
這里應用了Gradle提供的Java插件。該插件提供了構建和測試Java應用所需的一些東西。
一個最基本的Android工程的build.gradle如下:
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.11.1' } } apply plugin: 'android' android { compileSdkVersion 19 buildToolsVersion "19.0.0" }
在Android buid file中,有3個主要組成部分。
buildscript { ... }部分配置了驅動構建的代碼。
在該部分中,定義配置使用了Maven中央倉庫,并且聲明依賴一個Maven artifact(構件?)。 這個artifact是一個包含0.11.1版本的Android Gradle插件庫。
注意: 這部分的配置只會影響構建過程的代碼,和你的工程沒有關系。工程會定義它自己的倉庫和相關依賴。稍候會詳細介紹。
接下來,android插件被應用,這和上面的Java插件是一樣的。
最后,android { ... }這部分配置了android構建需要的所有參數。這里也是Android DSL的入口點。
默認情況下,只有編譯的目標SDK、構建工具的版本是必需的。就是compileSdkVersion和buildtoolsVersion兩個配置屬性。
compilation target和舊構建系統中的project.properties文件里 target 屬性是一樣的。這個新的屬性和以前的 target 一樣,可以指定一個int類型(api級別)或者string類的值。
重要: 你應該只應用android插件就好了,不要同時應用java插件,因為這會導致構建錯誤
注意: 你還需要在同目錄下添加一個 local.properties 文件,并通過sdk.dir屬性配置所需的SDK的路徑。除此之外,你也可以設置一個名為ANDROID_HOME環境變量。這兩種方法都差不多,你可以選擇自己喜歡的。
3.2 工程結構
上面說的build文件約定了一個默認的文件夾結構。Gradle遵循約定優先于配置的原則,在可能的情況下提供合理的默認值。
基本的工程始于兩個名為"source sets"的部分。也就是main source code 和 test code。他們分別位于:
- src/main
- src/androidTest/
里面的每一個文件夾都對應相應的組件。
對于Java和Android這兩個插件來說,他們的Java源代碼和Java資源的位置是:
- java/
- resources/
對于Android插件來說,它還有以下特性文件和文件夾:
- AndroidManifest.xml
- res/
- assets/
- aidl/
- rs/
- jni/
注意: src/androidTest/AndroidManifest.xml是不需要的,它會被自動創建。
3.2.1 配置結構
當默認的工程結構不適用的時候,你可能需要配置它。根據Gradle文檔說明,可以通過如下方式重新配置Java工程的sourceSets:
sourceSets { main { java { srcDir 'src/java' } resources { srcDir 'src/resources' } } }
注意: srcDir會添加指定的文件夾到現有的源文件夾列表中(Gradle文檔沒有提到這個,但是的確是這樣)。
要替換默認的源文件夾的話,可以給srcDirs指定一個路徑數組 。下面使用對象調用另一種方式配置:
sourceSets { main.java.srcDirs = ['src/java'] main.resources.srcDirs = ['src/resources'] }
想要了解更多的信息,請參考Gradle文檔的Java插件部分。
Android插件也使用相似的語法,但是它有它自己的 sourceSets ,這些已經內置在android對象中了。
這兒有個示例,它使用了舊工程結構的源代碼,并且重新映射了androidTest sourceSet 到測試文件夾:
android { sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } androidTest.setRoot('tests') } }
注意: 因為舊結構中把所有的源文件(java, aidl, renderscript, and java resources)都放在同一文件夾下,所以我們需要重新映射這些 sourceSet 的新組件到同一src目錄.
注意: setRoot()方法會移動整個 sourceSet (包括其下的子文件夾)到一個新文件夾。這里是移動src/androidTest/*到tests/*。
這些都是Android特有的,并不適用于Java sourceSets 。
這是一個遷移的例子(譯者注:比如從舊工程結構遷移過來)。
3.3 構建任務
3.3.1 通用任務
在構建文件中應用一個插件的時候會自動的創建一系列可運行的構建任務。Java plugin 和 the Android plugin都可以做到這一點。以下是約定的一些任務:
- assemble 這個任務會匯集工程的所有輸出。
- check 這個任務會執行所有校驗檢查
- build 這個任務會同時執行 assemble 和 check 任務
- clean 這個任務會清理工程的所有輸出
事實上, assemble , check 以及 build 這三個任務并沒有作任何事情,他們只是插件的引導任務,引導插件添加的其他任務去完成一些工作。
這樣就可以允許你調用同樣的任務,而不用管它是什么類型的工程或者應用了什么插件。
比如,應用 findbugs 插件會創建一個任務,并且讓 check 任務依賴它,這樣當這個 check 任務被調用的時候,這個新創建的任務也會被調用.
在命令行中輸入如下命令可以獲取一些高級別的任務介紹。
gradle tasks
要查看所有的任務列表以及任務之間的依賴關系運行:
gradle tasks --all
注意: Gradle會自動監控任務定義的輸入和輸出。
不做任何改變兩次運行 build ,Gradle會報告所有任務已經處于UP-TO-DATE狀態,這意味著沒有什么可做的。這使得任務之間可以正確的相互依賴,又不會導致其他不需要的操作執行。
3.3.2 Java工程任務
Java plugin創建了兩個主要的任務,主要的引導任務都依賴他們。
- assemble
- jar 這個任務創建所有輸出
- check
- test 這個任務運行所有測試
jar 任務直接或者間接的依賴其他任務:比如 classes 會編譯所有Java代碼.
testClasses 會編譯所有測試,但是它很少使用,因為 test這個任務依賴它(和 classes 差不多)。
通常情況下,你可能只用到 assemble 或者 check ,其他的任務不會使用。
你可以在這兒看到Java plugin的所有任務列表以及他們的依賴關系
3.3.3 Android任務
Android plugin使用了同樣的約定規則以和其他插件保持兼容,并且又添加了一些額外的引導任務:
- assemble 這個任務會匯集工程的所有輸出。
- check 這個任務會執行所有校驗檢查
- connectedCheck 運行checks需要一個連接的設備或者模擬器,這些checks將會同時運行在所有連接的設備上。
- deviceCheck 通過API連接遠程設備運行checks。它被用于CI(譯者注:持續集成)服務器上。
- build 這個任務會同時執行 assemble 和 check 任務
- clean 這個任務會清理工程的所有輸出
這些新的引導任務是必須的,以便能夠在沒有連接的設備的情況下運行定期檢查。
注意 build 既不依賴 deviceCheck ,也不依賴 connectedCheck 。
一個Android工程至少有兩個輸出:一個debug APK和一個release APK。他們每一個都有自己的引導任務以便可以單獨的構建他們:
- assemble
- assembleDebug
- assembleRelease
他們兩個都依賴其他任務,這些任務執行很多必須的步驟以生成一個APK。 assemble 任務又依賴他們兩個,所以執行 assemble 會生成兩個APK。
提示:在命令行下,Gradle支持任務名稱駝峰方式的快捷調用,比如:
gradle aR
和
gradle assembleRelease
是一樣的,當然前提是沒有其他任務匹配'aR'。
檢驗引導任務也有他們自己的依賴:
- check
- lint
- connectedCheck
- connectedAndroidTest
- connectedUiAutomatorTest (尚未實現)
- deviceCheck
- 這個依賴其他插件創建的時候實現的測試擴展點的哪些任務。
最后,插件會為所有的構建類型( debug, release, test )創建install/uninstall任務,也只有他們能被安裝(需要簽名)。
3.4 自定義構建
Android plugin提供了大量的DSL能夠讓你直接基于構建系統定制很多事情。
3.4.1 Manifest選項
通過DSL可以配置manifest的如下選項:
- minSdkVersion
- targetSdkVersion
- versionCode
- versionName
- applicationId (更有效的packageName -- 請看ApplicationId 與 PackageName獲取更多信息)
- Package Name for the test application
- Instrumentation test runner
示例:
android { compileSdkVersion 19 buildToolsVersion "19.0.0" defaultConfig { versionCode 12 versionName "2.0" minSdkVersion 16 targetSdkVersion 16 } }
android 元素里的 defaultConfig 負責定義所有的配置。
Android Plugin以前的版本是使用packageName配置manifest的'packageName'屬性。從0.11.0開始,你應該在build.gradle里使用applicationId來配置manifest的'packageName'屬性。這是為了消除應用的packageName(也就是ID)和java的packages之間的歧義。
通過build文件定義的強大之處在于可以動態的被配置。比如,可以從一個文件讀取版本名字,或者使用一些其他的自定義的邏輯:
def computeVersionName() { ... } android { compileSdkVersion 19 buildToolsVersion "19.0.0" defaultConfig { versionCode 12 versionName computeVersionName() minSdkVersion 16 targetSdkVersion 16 } }
注意: 不要使用在給定的范圍內,和其他已經存在的getters方法沖突的方法名字。比如在defaultConfig { ...}中調用getVersionName()方法會自動的調用defaultConfig.getVersionName()方法,如果你也自定義一個這樣的名字的方法,那么你的方法不會調用。
如果一個屬性沒有通過DSL設置,則會使用它們的默認值。這里有個表格說明是如何處理的。
屬性銘 | DSL對象的默認值 | 默認值 |
---|---|---|
versionCode | -1 | 如有有的話從manifest中讀取 |
versionName | null | 如有有的話從manifest中讀取 |
minSdkVersion | -1 | 如有有的話從manifest中讀取 |
targetSdkVersion | -1 | 如有有的話從manifest中讀取 |
applicationId | null | 如有有的話從manifest中讀取 |
testApplicationId | null | applicationId + “.test” |
testInstrumentationRunner | null | android.test.InstrumentationTestRunner |
signingConfig | null | null |
proguardFile | N/A (只能設置) | N/A (只能設置) |
proguardFiles | N/A (只能設置) | N/A (只能設置) |
如果你在構建腳本中使用自定義的邏輯獲取這些屬性的時候,那么第二列的值尤其重要。比如,你可能這樣寫:
if (android.defaultConfig.testInstrumentationRunner == null) { // assign a better default... }
如果值一直為null,那么在構建的時候,它將會被從第三列中獲取的實際的默認值替換,但是在DSL元素中又不包含這個默認值,所以你無法查詢到它。這是為了防止解析應用的manifest文件,除非真的需要。
3.4.2 構建類型
默認情況下,Android plugin會自動的設置工程,構建release和debug兩個版本。他們主要的差異主要在于是否可以在設備上調試應用以及APK如何簽名。
debug版本會被使用已知的名稱/密碼自動生成的密鑰/證書簽名。release版本在構建過程中不會被簽名,需要構建后再簽名。
這些配置可以通過一個叫 BuildType 配置。默認情況下,已經創建了 debug 和 release 這兩個實例。
Android plugin允許自定義這兩個示例,并且可以創建其他的 Build Types 。這些是可以在 buildTypes DSL容器中配置完成:
android { buildTypes { debug { applicationIdSuffix ".debug" } jnidebug.initWith(buildTypes.debug) jnidebug { packageNameSuffix ".jnidebug" jniDebuggable true } } }
以上的片段實現了以下幾點:
- 配置了默認的 debug 構建類型:
- 設置包名為.debug以便可以在同一設備上同時安裝 debug 和 release 兩個版本的APK
- 創建一個叫 jnidebug 新的 Build Types ,并且配置它作為 debug 構建類型的一個副本
- 然后再配置 jnidebug ,啟用JNI組件的debug構建,并且添加一個不同的包名后綴
創建一個新的 Build Types 很簡單,只需要在 buildTypes 容器下添加一個元素,然后調用 initWith() 或者使用一個閉包配置它。
這里有一些可能用到的屬性以及他們的默認值:
屬性名 | debug時的默認值 | release或者其他類型的默認值 |
---|---|---|
debuggable | true | false |
jniDebuggable | false | false |
renderscriptDebuggable | false | false |
renderscriptOptimLevel | 3 | 3 |
applicationIdSuffix | null | null |
versionNameSuffix | null | null |
signingConfig | android.signingConfigs.debug | null |
zipAlignEnabled | false | true |
minifyEnabled | false | false |
proguardFile | N/A (只能設置) | N/A (只能設置) |
proguardFiles | N/A (只能設置) | N/A (只能設置) |
除了這些屬性外, 代碼和資源也會影響到 Build Types 。對于每一個 Build Type,都會創建一個新的匹配的 sourceSet ,默認位置是
src/<buildtypename>/
這意味著 Build Type 的名字不能是 main 和 androidTest (這兩個已經被插件占用),并且他們相互之間的名字必須唯一。
和其他的source sets一樣,Build Type的source set的位置可以被重定向:
android { sourceSets.jnidebug.setRoot('foo/jnidebug') }
此外,對于每一個 Build Type ,都會新創建assemble<BuildTypeName>任務。
assembleDebug 和 assembleRelease 這兩個任務已經講過了,這里講的是他們是從哪來的。是在 debug 和 release 這兩個 Build Types 被預先創建的時候。
提示:記得你可以通過輸入gradle aJ來運行assembleJnidebug任務哦。
可能使用到的情況:
- 在debug模式下需要,但是在release下不需要的權限
- 自定義debug的實現
- 微debug默認使用不同的資源(比如一個資源的值是由簽名的證書決定的)
BuildType 的代碼/資源主要通過以下方式使用:
- manifest被合并進app的manifest
- 代碼僅僅是作為一個額外的source文件夾(譯者注:其實和自己新建一個source文件夾,然后在這個文件夾下新建包和類一樣)
- 資源會覆蓋main里的資源,替換現有的值
3.4.3 簽名配置
要對一個應用簽名,要求如下:
- 一個keystore
- 一個keystore的密碼
- 一個key的別名
- 一個key的密碼
- 存儲類型
位置、key別名、key密碼以及存儲類型一起組成了簽名配置( SigningConfig 類型)
默認情況下, 已經有了一個 debug 的簽名配置,它使用了debug keystore,該keystore有一個已知的密碼和默認的帶有已知密碼的key。 debug keystore位于$HOME/.android/debug.keystore,如果沒有會被創建。
debug Build Type 被設置為自動使用 debug 簽名配置。
你也可以創建其他的簽名配置或者自定義內置的配置。可以通過 signingConfigs DSL容器實現。
android { signingConfigs { debug { storeFile file("debug.keystore") } myConfig {ss storeFile file("other.keystore") storePassword "android" keyAlias "androiddebugkey" keyPassword "android" } } buildTypes { foo { debuggable true jniDebuggable true signingConfig signingConfigs.myConfig } } }
以上片段會把debug keystore的路徑改為工程的根目錄。這會自動的影響任何用到它的 Build Types ,在這里影響到的是 debug Build Type 。
以前片段也創建了一個新的簽名配置,并且被一個新的 Build Type 使用。
注意: 只有默認路徑下的debug keystores才會被自動創建。如果改變了debug keystore的路徑將不會在需要的時候創建。創建一個使用不同名字的 SigningConfig ,但是用的是默認的debug keystore路徑的話是會被自動創建的。也就是說,會不會被自動創建,和keystore的路徑有關,和配置的名字無關。
說明: 通常情況下,會使用工程根目錄的相對路徑作為keystores的路徑,但有時候也會用絕對路徑,雖然這并不推薦(被自動創建的debug keystore除外)。
注意:如果已經你將這些文件放到版本控制中,你可能不想把密碼存儲在文件中。Stack Overflow上有個帖子介紹可以從控制臺或者環境變量中獲取這些密碼等信息。
http://stackoverflow.com/questions/18328730/how-to-create-a-release-signed-apk-file-using-gradle
我們以后更新這個指南的時候會添加更多的信息。
3.4.4 使用混淆
自從Gradle plugin for ProGuard 4.10版本以后,Gradle開始支持混淆。如果通過Build Type的 minifyEnabled 屬性配置了使用混淆后,The ProGuard plugin會自動被應用,并且自動創建一些任務。
android { buildTypes { release { minifyEnabled true proguardFile getDefaultProguardFile('proguard-android.txt') } } productFlavors { flavor1 { } flavor2 { proguardFile 'some-other-rules.txt' } } }
使用buildTypes以及productFlavors定義的規則文件可以輕松的生成多種版本。
有兩個默認的規則文件
- proguard-android.txt
- proguard-android-optimize.txt
他們位于SDK中,使用getDefaultProguardFile()方法可以返回文件的全路經。除了是否啟用優化之外,這兩個文件的其他功能都是相同的。
3.4.5 清理資源
在構建的時候,你也可以自動的移除一些未使用的資源。更多信息,請參考資源清理文檔
4 依賴,Android庫工程以及多工程設置
Gradle可以依賴其他的一些組件,這些組建可以是外部二進制包,也可以是其他Gradle工程。
4.1 依賴二進制包
4.1.1 本地包
要配置依賴一個外部庫jar包,你可以在 compile 配置里添加一個依賴。
dependencies { compile files('libs/foo.jar') } android { ... }
注: dependencies DSL元素是標準Gradle API的一部分,并不屬于 android 的元素。
compile 配置用來編譯main application,它里面的一切都會被添加到編譯的classpath中,并且也會被打包到最終的APK中。
這里還有添加依賴時其他的配置:
- compile: main application
- androidTestCompile: test application
- debugCompile: debug Build Type
- releaseCompile: release Build Type
因為要構建生成一個APK,必然會有相關聯的 Build Type ,APK默認配置了兩個(或者更多)編譯配置:compile和<buildtype>Compile。創建一個新的 Build Type 的時候會自動創建一個基于它名字的編譯配置。
當一個debug版本需要一個自定義庫(比如報告崩潰),但是release版本不需要或者需要一個不同版本的庫的時候,會顯得非常有用。
4.1.2 遠程 artifacts
Gradle支持從Maven和Ivy倉庫獲取artifacts。
首先必須把庫添加到列表中,并且以Maven或者Ivy的定義方式定義需要的依賴。
repositories { mavenCentral() } dependencies { compile 'com.google.guava:guava:11.0.2' } android { ... }
注: mavenCentral() 是指定倉庫URL的快捷方式。Gradle同時支持遠程和本地兩種倉庫注:Gradle遵循依賴的傳遞性。這就意味著如果依賴本身會依賴其他東西,這些也會被拉取過來。
更多關于dependencies的設置信息,請參見Gradle 用戶指南,以及DSL文檔
4.2 多工程設置
Gradle工程可以通過多工程配置依賴其他的Gradle工程
多工程配置通常把所有的工程作為根目錄的子文件夾。
比如,下面的工程結構:
MyProject/ app/ libraries/ lib1/ lib2/
我們可以識別這三個工程。Gradle會通過如下名字引用他們:
:app :libraries:lib1 :libraries:lib2
每個工程都有屬于它自己的build.gradle文件定義如何構建它自己。
此外,在工程根目錄下有個叫 settings.gradle 的文件會定義所有工程。
文件結構如下:
MyProject/ settings.gradle app/ build.gradle libraries/ lib1/ build.gradle lib2/ build.gradlef
settings.gradle里的內容非常簡單:
include ':app', ':libraries:lib1', ':libraries:lib2'
這里定義了哪個文件是一個Gradle工程。
:app 工程也可能會依賴一些庫工程,可以通過如下腳本聲明依賴:
dependencies { compile project(':libraries:lib1') }
更多關于多工程的配置請參考這里
4.3 庫工程
在上面的多工程配置中,:libraries:lib1 和 :libraries:lib2 可能是Java工程,并且 :app Android工程會用到他們生成的jar報。
但是,如果你想共享訪問Android API的代碼或者使用Android的樣式資源,那么這個庫工程就不能是通常的Java工程,而應該是Android庫工程。
4.3.1 創建一個庫工程
一個Android庫工程和一個Android工程非常相似,只有一點差別。
因為構建一個庫和構建一個應用不太一樣,所以它使用了一個不同的插件。這兩個插件(構建應用和庫的)大部分代碼都是一樣,并且都是通過com.android.tools.build.gradle jar包提供。
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.5.6' } } apply plugin: 'android-library' android { compileSdkVersion 15 }
這里創建一個基于API 15級別編譯的庫工程。SourceSets ,以及依賴的處理方式和應用工程是一樣并且可以以同樣的方式進行自定義。
4.3.2 普通工程和庫工程的不同
庫工程的main輸出是一個.aar報(這個一個標準的Android存檔).它由編譯后的代碼(比如jar文件或者.so文件)以及資源文件(manifest, res, assets)組成。庫工程也可以生成一個測試apk,可以獨立于應用進行測試。
它有相同的引導任務( assembleDebug , assembleRelease ),所以他和一般的工程沒有什么不同。
其余的,基本上都和應用一樣了。他們都有build types和product flavors,可以生成多個版本的aar。注意 Build Type 大部分配置并不適用于庫工程。不過你可以依據庫工程是被其他工程依賴還是測試,然后通過自定義庫工程 sourceSet 改變它的內容。
4.3.3 引用一個庫工程
引用一個庫工程和引用其他工程是一樣的:
dependencies { compile project(':libraries:lib1') compile project(':libraries:lib2') }
說明:如果你有多個依賴庫工程, 順序是很重要的。這和舊構建系統中在project.properties文件中定義的依賴順序是一樣的。
4.3.4 庫工程發布
默認情況下庫工程只能發布 release 版本。這個版本用于所有工程的引用,和工程本身要構建什么樣的版本無關。這是屬于Gradle的限制,我們正在努力消除這個限制。
你可以通過如下方式控制發布的各種版本
android { defaultPublishConfig "debug" }
注意這里的發布配置的名字使用的是一個完整的版本名字。 Release 和 debug 僅僅適用于沒有其他版本的時候使用。如果你想用其他版本代替默認發布的版本,你可以這么做:
android { defaultPublishConfig "flavor1Debug" }
發布庫工程的所有不同版本也是可能的。我們計劃在在一般的工程對工程依賴中(就像上面說的)允許這么做。但是這還不被Gradle允許(我么正在努力修復這個問題)。
默認情況下,沒有啟用發布所有不同的版本功能,你可以這么啟用他們:
android { publishNonDefault true }
要意識到,發布多個不同的版本意味著會有多個aar文件,而不是一個aar文件中包含多個不同的版本。每個aar包只包含一個版本。發布一個版本意味著要生成一個可用的aar文件作為Gradle工程的輸出構件。它既可以被發不到一個maven倉庫,也可以被其他工程依賴引用。
Gradle有默認‘構件’的概念,當作如下配置時會用到:
compile project(':libraries:lib2')
要創建另外一個已發布構建的依賴,你需要指定需要哪一個:
dependencies { flavor1Compile project(path: ':lib1', configuration: 'flavor1Release') flavor2Compile project(path: ':lib1', configuration: 'flavor2Release') }
重要: 注意發布配置的是一個完整的版本,包括build type,并且需要像上面一樣被引用。
重要: 當啟用了非默認發布的時候,Maven的發布插件將會發布其他版本作為擴展包(按分級)。這意味著和maven上的版本不一定兼容。你應該發布一個單獨的版本到倉庫中或者為工程間的依賴啟用所有的發布配置。
5 測試
構建的測試應用已經被集成在應用工程里,不需要再創建一個單獨的測試工程。
5.1 基礎介紹和配置
正如上面講到的, main sourceSet 的旁邊就是 androidTest sourceSet ,默認的路徑是src/androidTest/ 從這個 sourceSet 可以構建一個能安裝到設備上的測試apk,該apk使用Android測試框架測試應用。這里包括單元測試、集成測試以及后續的UI自動化測試。這個測試 sourceSet 不必包含AndroidManifest.xml文件,因為它會自動生成。
測試應用有如下值可以配置:
- testPackageName
- testInstrumentationRunner
- testHandleProfiling
- testFunctionalTest
如前所見,這些可以在 defaultConfig 對象里配置。
android { defaultConfig { testPackageName "com.test.foo" testInstrumentationRunner "android.test.InstrumentationTestRunner" testHandleProfiling true testFunctionalTest true } }
在測試應用的manifest文件中,instrumentation節點的targetPackage屬性值會自動的被測試應用的包名填充,即使是通過defaultConfig或者Build Type對象定義的。這也是manifest文件自動生成的一個原因。
此外,sourceSet 也可以配置它自己的依賴。默認情況下,應用以及它自己的依賴會被添加測試應用的classpath中,但是也可以進行擴展
dependencies { androidTestCompile 'com.google.guava:guava:11.0.2' }
測試應用通過 assembleTest 任務來構建。它并不依賴main的 assemble 任務,并且不能自動調用,需要手動運行。
當前只能同時測試一個 Build Type ,默認是 debug Build Type ,但是也可以被重新配置
android { ... testBuildType "staging" }
5.2 運行測試
正如前面所提到的,引導任務 connectedCheck 需要一個已經連接的設備才能運行。這會依賴 androidTest ,所以 androidTest 也會被運行。這個任務做了以下事情:
- 確保應用和測試應用已經被構建(依賴 assembleDebug 和 assembleTest )
- 安裝這兩個應用
- 運行測試
- 卸著這兩個應用
如果同時有多個連接的設備,那么所有的測試會在所有的設備上運行。不管在哪個設備上,只要有一個測試失敗,那么整個構建就是失敗的。
所有的測試結果已XML的格式被存儲在build/androidTest-results目錄下。 (這類似于jUnit,它的結果存儲在build/test-results)目錄下)
當然,你可以自己設置
android { ... testOptions { resultsDir = "$project.buildDir/foo/results" } }
android.testOptions.resultsDir 的值是通過 Project.file(String) 得到。
5.3 測試Android庫
測試Android庫工程的方式和應用工程是一樣。
僅有的不同就是整個庫(包括它的依賴)會作為一個依賴庫被自動的添加到測試應用中。測試APK的測試結果不僅包括它自己代碼的測試,還包括Android庫的以及庫的所有依賴的測試。庫的manifest被合并到測試應用的manifest中(這種情況就和任何工程引用這個庫是一樣的)
androidTest 任務的職責也不一樣了,它僅僅負責安裝(和卸載)測試APK(因為也沒有其他APK需要安裝)
其他的都和測試應用差不多。
5.4 測試報告
當運行單元測試的時候,Gradle會生成一份HTML報告以便于查看測試結果。 Android plugins在這個基礎上擴展了HTML報告,以合并所有已連接設備上的測試結果。
5.4.1 單工程報告
在運行測試的時候工程會自動的生成報告,默認位置是:
build/reports/androidTests
這和jUnit報告的位置build/reports/tests很相似,其他報告的位置通常是build/reports/<plugin>/
報告的位置也可以自定義
android { ... testOptions { reportDir = "$project.buildDir/foo/report" } }
報告會合并運行在不同設備上的測試結果。
5.4.2 多工程報告
在一個既有應用工程又有庫工程的多工程里,當在同時運行所有測試的時候,生成一個包含所有測試結果的報告是非常有用的。
為了達到這一目的,需要同一構件中的另外一個插件,可以通過如下方式應用:
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.5.6' } } apply plugin: 'android-reporting'
這應該被應用到根目錄下,也就是和settings.gradle相鄰的build.gradle文件中.
然后,在根目錄打開終端,輸入如下命令運行所有測試并且收集報告:
gradle deviceCheck mergeAndroidReports --continue
注:--continue選項確保所有測試都被執行,即使測試是失敗的.否則的話第一個失敗的測試會中斷運行,那么就可能會有一些工程的測試不會被運行.
5.5 Lint支持
從0.7.0版本之后,你可以為一個特定的變種版本運行lint,也可以為所有變種版本都運行.在這種情況下,它會產生一個報告指出給定的變種版本的問題.
你可以像下面一樣通過lintOptions自定義lint.一般情況下,你只需要配置其中的一部分.以下是展示所有可用的lint配置項.
android { lintOptions { // set to true to turn off analysis progress reporting by lint quiet true // if true, stop the gradle build if errors are found abortOnError false // if true, only report errors ignoreWarnings true // if true, emit full/absolute paths to files with errors (true by default) //absolutePaths true // if true, check all issues, including those that are off by default checkAllWarnings true // if true, treat all warnings as errors warningsAsErrors true // turn off checking the given issue id's disable 'TypographyFractions','TypographyQuotes' // turn on the given issue id's enable 'RtlHardcoded','RtlCompat', 'RtlEnabled' // check *only* the given issue id's check 'NewApi', 'InlinedApi' // if true, don't include source code lines in the error output noLines true // if true, show all locations for an error, do not truncate lists, etc. showAll true // Fallback lint configuration (default severities, etc.) lintConfig file("default-lint.xml") // if true, generate a text report of issues (false by default) textReport true // location to write the output; can be a file or 'stdout' textOutput 'stdout' // if true, generate an XML report for use by for example Jenkins xmlReport false // file to write report to (if not specified, defaults to lint-results.xml) xmlOutput file("lint-report.xml") // if true, generate an HTML report (with issue explanations, sourcecode, etc) htmlReport true // optional path to report (default will be lint-results.html in the builddir) htmlOutput file("lint-report.html") // set to true to have all release builds run lint on issues with severity=fatal // and abort the build (controlled by abortOnError above) if fatal issues are found checkReleaseBuilds true // Set the severity of the given issues to fatal (which means they will be // checked during release builds (even if the lint target is not included) fatal 'NewApi', 'InlineApi' // Set the severity of the given issues to error error 'Wakelock', 'TextViewEdits' // Set the severity of the given issues to warning warning 'ResourceAsColor' // Set the severity of the given issues to ignore (same as disabling the check) ignore 'TypographyQuotes' } }
6 Build Variants(構建變種版本)
新構建系統的目標之一就是為同一個應用創建不同的版本。
主要有兩個使用場景:
- 同一個應用的不同版本。比如一個免費的版本和一個付費的專業版本。
- 同一個應用被打包成多個不同的apk以發布到Google Play商店。詳情請見http://developer.android.com/google/play/publishing/multiple-apks.html
- 綜合第1條和第2條。
我們的目標就是基于同一個工程生成不同的APK,而不是使用一個單獨的庫工程和兩個以上的應用工程組合生成APK的方式。
6.1 Product flavors(產品定制)
一個product flavor定義了可以通過工程構建應用的自定義版本。一個獨立的工程可以定義不同的flavor改變生成的應用。
這種被設計的新概念對于版本間差異非常小的時候很有用。如果“這是同一個應用嗎?”的答案是肯定的話,那么這種方式的確比使用庫工程的方式要好得多。(譯者注:以前的方法要生成多個包,可能是從采用多個不同的應用工程+一個庫工程的方式,現在這種新的方式比我們以前的老方式好多了)
Product flavors 是通過 productFlavors DSL容器定義的:
android { .... productFlavors { flavor1 { ... } flavor2 { ... } } }
這里創建了兩個flavors,分別是flavor1和flavor2. 注意:flavors的名字不能和已存在的 Build Type 名字或者 androidTest sourceSet 沖突。
6.2 Build Type(構建類型) + Product Flavor(產品定制) = Build Variant(構建變種版本)
正如我們前面看到的,每一個 Build Type 都會生成一個新的APK。
Product Flavors 也是這么做的:工程的輸出將會盡可能的組合 Build Types 和 Product Flavors 的輸出。
每一種組合(Build Type, Product Flavor)就是 構建變種
比如,以默認的 debug 和 release Build Types 為例,上面的例子會生成四個 Build Variants :
- Flavor1 - debug
- Flavor1 - release
- Flavor2 - debug
- Flavor2 - release
沒有flavors的工程仍然是有 Build Variants 的,只是使用的是默認的flavor和配置,并且沒有名字,所以variants的列表看起來和Build Types列表一樣。
6.3 Product Flavor Configuration(產品定制配置)
每一個flavors都可以通過一個閉包配置:
android { ... defaultConfig { minSdkVersion 8 versionCode 10 } productFlavors { flavor1 { packageName "com.example.flavor1" versionCode 20 } flavor2 { packageName "com.example.flavor2" minSdkVersion 14 } } }
要知道的是 android.productFlavors.* 是 ProductFlavor 類型的,和 android.defaultConfig 對象具有相同的類型,者意味著他們有相同的屬性。
defaultConfig 為所有的flavor提供了基本的配置,每一個flavor也都可以重新設置覆蓋這些默認值。在上面的例子中,最終的配置如下:
- flavor1
- packageName: com.example.flavor1
- minSdkVersion: 8
- versionCode: 20
- flavor2
- packageName: com.example.flavor2
- minSdkVersion: 14
- versionCode: 10
通常情況下,Build Type 配置會覆蓋其他配置,比如,Build Type 的 packageNameSuffix 會追加到 Product Flavor 的 packageName 之后。
也有一些情況是在 Build Type 和 Product Flavor 中都可以設置,在這種情況下,視情況而定。
比如, signingConfig 就是這么一個屬性。通過設置 android.buildTypes.release.signingConfig ,可以為所有的release包共享相同的SigningConfig,也可以單獨通過設置android.productFlavors..signingConfig為每一個release包指定他們自己的 *SigningConfig 。
6.4 Sourcesets and Dependencies(Sourcesets和依賴)
類似 Build Types , Product Flavors 也可以通過他們自己的 sourceSets 控制代碼和資源。
上面的例子會創建4個 sourceSets :
- android.sourceSets.flavor1 ,位置是src/flavor1/
- android.sourceSets.flavor2 ,位置是src/flavor2/
- android.sourceSets.androidTestFlavor1 ,位置是src/androidTestFlavor1/
- android.sourceSets.androidTestFlavor2 ,位置是src/androidTestFlavor2/
這些 sourceSets 和 android.sourceSets.main 以及 Build Type sourceSet 一起構建APK。
當處理所有的 sourcesets 以構建一個單獨的APK的時候,下面的規則會被應用:
- 所有的源代碼(src/*/java)會以多文件夾的方式一起被使用生成一個輸出。
- 所有Manifest文件會合并成一個manifest文件。這允許 Product Flavors 有一些不同的組件定義或者權限聲明,類似于 Build Types 。
- 所有的資源(Android res和assets)都會遵循優先級覆蓋的原則, Build Type 會覆蓋 Product Flavorg ,最后又都會覆蓋 main sourceSet .
- 每一個 Build Variant 會基于資源生成他們自己的R類(或者生成其他的源代碼),variant之間不會共享。
最后,像 Build Types, Product Flavors 也可以有他們自己的依賴。比如,如果flavor用來生成一個廣告app和一個付費的app,其中一個flavor可能需要依賴一個廣告SDK,另外一個則不需要。
dependencies { flavor1Compile "..." }
在這種特定的情況下,src/flavor1/AndroidManifest.xml文件可能需要包含訪問網絡的權限聲明。
此外,也會為每一個variant創建一個sourcesets:
- android.sourceSets.flavor1Debug ,位置是src/flavor1Debug/
- android.sourceSets.flavor1Release ,位置是src/flavor1Release/
- android.sourceSets.flavor2Debug ,位置是src/flavor2Debug/
- android.sourceSets.flavor2Release ,位置是src/flavor2Release/
這些sourcesets擁有比build type更高的優先級,并且允許在variant級別上做一些定制。
6.5 Building and Tasks(構建和任務)
我們在前面說過,每一個 Build Type 都會創建它自己的 assemble<name>任務,但是Build Variants的任務則是Build Type和Product Flavor的組合。
當Product Flavors被使用的時候,更多的assemble-type任務被創建,他們是:
- assemble<Variant Name> 允許直接構建一個variant版本。例如 assembleFlavor1Debug
- assemble<Build Type Name> 允許根據給定的Build Type構建所有的APK。例如 assembleDebug 會同時構建Flavor1Debug和Flavor2Debug兩個variant版本。
- assemble<Product Flavor Name> 允許根據給定的flavor構建所有的APK。例如 assembleFlavor1 會同時構建Flavor1Debug和Flavor1Release兩個variant版本。
assemble 任務會盡可能的構建所有variant版本。
6.6 Testing(測試)
測試多flavor工程和測試普通的工程差不多。
androidTest sourceset對所有的flavor來說是通用的測試,而每個flavor也可以有他們自己的測試。
正如前面所提到的,每一個flavor都可以創建自己的測試 sourceSets :
- android.sourceSets.androidTestFlavor1 ,位置是src/androidTestFlavor1/
- android.sourceSets.androidTestFlavor2 ,位置是src/androidTestFlavor2/
同樣的,他們也可以有他們自己的依賴:
dependencies { androidTestFlavor1Compile "..." }
運行測試可以通過主的 deviceCheck 引導任務,當使用flavor的時候,也可以通過主的 androidTest 引導任務來執行。
每一個flavor都有他們自己運行測試的任務:androidTest<VariantName>。例如:
- androidTestFlavor1Debug
- androidTestFlavor2Debug
同樣的,每一個variant也都有測試APK任務、安裝以及卸載任務:
- assembleFlavor1Test
- installFlavor1Debug
- installFlavor1Test
- uninstallFlavor1Debug
- ...
最終的HTML報告會根據flavor合并生成。
測試結果以及報告的位置如下,第一個是每個flavor的結果,然后是合并起來的:
- build/androidTest-results/flavors/<FlavorName>
- build/androidTest-results/all/
- build/reports/androidTests/flavors<FlavorName>
- build/reports/androidTests/all/
自定義路徑的話,也只是改變根目錄,仍然會創建每個flavor的子文件夾并且合并測試結果以及報告。
6.7 Multi-flavor variants(多種定制的版本)
有些情況下,人們想基于不同的標準創建同一應用的幾個不同的版本。例如,Google Play里的multi-apk支持4種不同的過濾器。為每一個過濾器創建不同的APK就需要用到多維度的 Product Flavor了。
考慮到一個游戲有一個演示版本和一個付費版本,并且在multi-apk支持中需要用到ABI過濾器。3個ABI和兩個版本的情況下,就會有6個APK生成(沒有計算不同的Build Type的variant版本)。然而,對于三個ABI來說,他們的付費版本的代碼都是一樣的,因此只是簡單的創建6個flavor并不是一個好辦法。相反的,使用兩個flavor維度,并且自動構建所有可能的variants。
這個功能通過Flavor Dimensions能實現。Flavors會被指定到特定的維度。
android { ... flavorDimensions "abi", "version" productFlavors { freeapp { flavorDimension "version" ... } x86 { flavorDimension "abi" ... } } }
android.flavorDimensions 數據定義了可能用到的唯獨以及順序。每一個定義的 Product Flavor 都會被指定一個緯度。
從Product Flavors [freeapp, paidapp]、[x86, arm, mips]、[debug, release] Build Types維度,會有以下build variant被創建:
- x86-freeapp-debug
- x86-freeapp-release
- arm-freeapp-debug
- arm-freeapp-release
- mips-freeapp-debug
- mips-freeapp-release
- x86-paidapp-debug
- x86-paidapp-release
- arm-paidapp-debug
- arm-paidapp-release
- mips-paidapp-debug
- mips-paidapp-release
通過 android.flavorDimensions 定義的維度的順序是非常重要的。
每一個variant都會被如下幾個 Product Flavor 對象配置:
- android.defaultConfig
- abi維度
- version維度
維度的順序決定了哪一個flavor會覆蓋哪一個flavor,這對于資源來說非常重要,因為flavor會替換掉定義在低優先級flavor中的值。 flavor維度首先使用高優先級的定義。在這里是:
abi > version > defaultConfig
Multi-flavors工程也有額外的sourcesets。類似variant的sourcesets,只是沒有build type。
- android.sourceSets.x86Freeapp ,位置是src/x86Freeapp/
- android.sourceSets.armPaidapp ,位置是src/armPaidapp/
- 等等...
這允許你在flavor-combination級別上進行定制。他們比普通的flavor sourcesets優先級高,但是比build type sourcesets優先級低。
7 高級構建定制
7.1 構建選項
7.1.1 Java編譯選項
android { compileOptions { sourceCompatibility = "1.6" targetCompatibility = "1.6" } }
默認值是1.6。這個設置會影響所有編譯java源代碼的任務。
7.1.2 aapt選項
android { aaptOptions { noCompress 'foo', 'bar' ignoreAssetsPattern "!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~" } }
這會影響所有使用appt的任務。
7.1.3 dex選項
android { dexOptions { incremental false preDexLibraries = false jumboMode = false javaMaxHeapSize "2048M" } }
這會影響所有使用dex的任務
7.2 操縱任務
普通的Java工程有一個有限的任務集合,這些任務相互配合創建一個輸出。 classes 是一個編譯Java源代碼的任務。在build.gradle中通過腳本訪問和使用classes任務是很簡單的。可以通過project.tasks.classes快捷訪問。
對于Android工程來說就比較復雜了,因為可能有很多相同的任務,他們的名字是基于 Build Types和Product Flavors 生成的。
為了解決這個問題, android 對象提供了兩個屬性:
- applicationVariants (僅僅適用于app plugin)
- libraryVariants (僅僅適用于library plugin)
- testVariants (兩種plugin都適用)
ApplicationVariant, LibraryVariant, and TestVariant這三個對象都會分別返回一個DomainObjectCollection。
請注意訪問這些集合中的任何一個都會觸發生成所有的創建。這意味著訪問這些集合后無須重新配置就會產生。
DomainObjectCollection允許直接的訪問所有對象,或者通過更為方便的過濾器訪問。
android.applicationVariants.each { variant -> .... }
這三個variant類都具有以下屬性:
屬性名 | 屬性類型 | 說明 |
---|---|---|
name | String | variant的名字,必須是唯一的。 |
description | String | variant的可讀性的描述 |
dirName | String | variant的子文件夾名稱,必須是惟一的。可能還不止一個,比如 “debug/flavor1” |
baseName | String | variant輸出的的基本名稱,必須是唯一的。 |
outputFile | File | variant的輸出,是一個可讀寫的屬性 |
processManifest | ProcessManifest | 處理manifest的任務 |
aidlCompile | AidlCompile | 編譯AIDL文件的任務 |
renderscriptCompile | RenderscriptCompile | 編譯Renderscript文件的任務 |
mergeResources | MergeResources | 合并資源的任務 |
mergeAssets | MergeAssets | 合并資源的任務 |
processResources | ProcessAndroidResources | 處理和編譯資源的任務 |
generateBuildConfig | GenerateBuildConfig | 生成BuildConfig類的任務 |
javaCompile | JavaCompile | 編譯Java代碼的任務 |
processJavaResources | Copy | 處理Java資源的任務 |
assemble | DefaultTask | 這個variant的assemble引導任務 |
ApplicationVariant類還有以下屬性:
屬性名 | 屬性類型 | 說明 |
---|---|---|
buildType | BuildType | variant的BuildType。 |
productFlavors | List<ProductFlavor> | variant的ProductFlavors,不能為空,但可以是空值 |
mergedFlavor | ProductFlavor | android.defaultConfig和variant.productFlavors合并 |
signingConfig | SigningConfig | 這個variant使用的SigningConfig對象 |
isSigningReady | boolean | 如果為true則說明variant已經具備簽名所需的一切信息 |
testVariant | BuildVariant | 將會測試這個variant的TestVariant |
dex | Dex | dex代碼的任務,如果variant是一個庫可以為null |
packageApplication | PackageApplication | 生成最終AP看的任務,如果variant是一個庫可以為null |
zipAlign | ZipAlign | zip壓縮apk的任務,如果variant是一個庫或者APK不能被簽名可以為null |
install | DefaultTask | 安裝任務,可以為null。 |
uninstall | DefaultTask | 卸載任務 |
LibraryVariant類還有以下屬性:
屬性名 | 屬性類型 | 說明 |
---|---|---|
buildType | BuildType | variant的BuildType |
mergedFlavor | ProductFlavor | 就是defaultConfig |
testVariant | BuildVariant | 將要測試這個variant的Build Variant |
packageLibrary | Zip | 把庫打包成一個AAR存檔的任務,如果不是一個庫值為Null |
TestVariant類還有以下屬性:
屬性名 | 屬性類型 | 說明 |
---|---|---|
buildType | BuildType | variant的BuildType。 |
productFlavors | List<ProductFlavor> | variant的ProductFlavors,不能為空,但可以是空值 |
mergedFlavor | ProductFlavor | android.defaultConfig和variant.productFlavors合并 |
signingConfig | SigningConfig | 這個variant使用的SigningConfig對象 |
isSigningReady | boolean | 如果為true則說明variant已經具備簽名所需的一切信息 |
testVariant | BaseVariant | 將會測試這個variant的BaseVariant |
dex | Dex | dex代碼的任務,如果variant是一個庫可以為null |
packageApplication | PackageApplication | 生成最終AP看的任務,如果variant是一個庫可以為null |
zipAlign | ZipAlign | zip壓縮apk的任務,如果variant是一個庫或者APK不能被簽名可以為null |
install | DefaultTask | 安裝任務,可以為null。 |
uninstall | DefaultTask | 卸載任務 |
connectedAndroidTest | DefaultTask | 在已連接的設備上運行android測試的任務 |
providerAndroidTest | DefaultTask | 使用擴展的API運行android測試的任務 |
Android特定任務類型的API
- ProcessManifest
- File manifestOutputFile
- AidlCompile
- File sourceOutputDir
- RenderscriptCompile
- File sourceOutputDir
- File resOutputDir
- MergeResources
- File outputDir
- MergeAssets
- File outputDir
- ProcessAndroidResources
- File manifestFile
- File resDir
- File assetsDir
- File sourceOutputDir
- File textSymbolOutputDir
- File packageOutputFile
- File proguardOutputFile
- GenerateBuildConfig
- File sourceOutputDir
- Dex
- File outputFolder
- PackageApplication
- File resourceFile
- File dexFile
- File javaResourceDir
- File jniDir
- File outputFile
- To change the final output file use "outputFile" on the variant object directly.
- ZipAlign
- File inputFile
- File outputFile
- To change the final output file use "outputFile" on the variant object directly.
每一個任務類型的API都會因為Gradle的工作方式以及Android plugin的設置受到限制。首先,Gradle限制只能配置任務的輸入/輸出以及一些可選的標志。所以,這里的這些任務只能定義輸入/輸出。
其次,大多數任務的輸入并不唯一,通常會混合sourceSets,Build Types以及Product Flavors。為了保持構建簡單以及可讀性,我們的目標是讓開發者通過DSL通過這些對象修改構建,而不是深入的了解任務的輸入和選項進而修改它們。
還要注意的是,除了ZipAlign任務類型,其他所有的任務都需要設置私有數據讓他們運行。這就意味著不能基于這些類型手動的創建新的任務。
對于Gradle的任務(DefaultTask, JavaCompile, Copy, Zip),請參考Gradle文檔。
7.3 BuildType and Product Flavor的屬性參考
即將推出。對于Gradle的任務(DefaultTask, JavaCompile, Copy, Zip),請參考Gradle文檔。
7.4 使用sourceCompatibility 1.7
基于Android KitKat (buildToolsVersion 19)開發的時候,你能用diamond operator, multi-catch, strings in switches, try with resources等等這些新的特性。要做到這些,你需要把下面的配置添加到你的構建文件中:
android { compileSdkVersion 19 buildToolsVersion "19.0.0" defaultConfig { minSdkVersion 7 targetSdkVersion 19 } compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7 } }
需要注意的是你也可以把 minSdkVersion 設置為19之前的版本,這樣的話你只能使用除try with resources之外的語言特性。如果你想使用try with resources,你需要設置 minSdkVersion 為19。
你還需要確認Gradle使用的JDK1.7或者之后的版本。(并且Android Gradle plugin同樣也需要0.6.1或者之后的版本)
來自:https://github.com/rujews/android-tech-docs/blob/master/new-build-system/user-guide/README.md