不知道是什麼網絡問題,上午一直髮不了博客,其他頁面基本正常,就是在寫博客這裏,每次打開都是響應超時。剛纔用了VPN,順便試了一下,居然可以編輯。想是CDN之類的問題吧。
這次翻譯的是Gradle 插件用戶指南,也就是Gradle上的Android插件的官方文檔。文檔很長,加上最近激情不夠,翻譯得有些慢。到昨天爲止,才譯到第四章。今天先發前三章。
本文譯自Android官方技術文檔《Gradle Plugin User Guide》,原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide。
翻譯不易,轉載請註明CSDN博客上的出處:
http://blog.csdn.net/maosidiaoxian/article/details/41944325
翻譯工作耗時費神,如果你覺得本文翻譯得還OK,請點一下“頂”,我在精神上會倍受鼓勵的,謝謝。翻譯如有錯訛,敬請指正。
Gradle 插件用戶指南
簡介
新構建系統的目標
- 可以很容易地重用代碼和資源
- 可以很容易地創建應用程序的幾個變種,無論是多APK分發還是不同定製版的應用程序
- 可以很容易地配置、 擴展和自定義構建過程
- 好的 IDE 集成
基於Gradle的以下特點,我們選擇了它:
- 域特定語言 (DSL) 來描述和處理構建邏輯
- 構建文件基於 Groovy ,並允許通過 DSL來混合聲明性元素,以及使用代碼來處理 DSL 元素以提供自定義邏輯。
- 基於 Maven 和 Ivy 的內置依賴管理。
- 非常靈活。允許使用最佳實現,但並不強制自己的實現方式。
- 插件可以提供自己的 DSL 和API供構建文件使用。
- 良好的Tooling API 供 IDE 集成
要求
- Gradle 版本需要 1.10,1.11或 1.12。插件版本需要 0.11.1
- SDK Build Tools版本要求爲 19.0.0。某些功能可能需要更高版本。
基本項目
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"
}
buildscript { ... }配置了驅動構建的代碼。
在上面的這種情況中,它聲明瞭使用 Maven 中央庫,並且對一個Maven 文件有一個類路徑依賴。這個文件是包含 Gradle Android 插件的 0.11.1版本的庫
注: 這隻會影響運行構建的代碼,不會影響項目的源代碼。項目本身需要定義它自己的倉庫和依賴關係。稍後會提及這部分。
然後,和先前的提到的 Java 插件一樣,這裏配置使用了 android插件。
最後, android { ... }配置了用於 android 構建的所有參數。這是Android DSL的入口。
默認情況下,只需要配置編譯目標,以及build-tools的版本。它通過compileSdkVersion和buildtoolsVersion屬性來完成。
重要提示:你應該只配置使用這個android插件。如果同時配置使用了java插件也會導致構建錯誤。
注:您還需要一個local.properties文件,通過sdk.dir屬性來設置 SDK 的位置,並且所設置的這個SDK要求存在。
或者,您也可以設置一個ANDROID_HOME環境變量。這兩種方法之間沒什麼差別,你喜歡,你選擇。
基本項目開始於兩個名爲“source sets”的組件。即主源代碼和測試代碼。它們分別在:
- src/main/
- src/androidTest/
對於 Java 和 Android 插件,Java 源代碼和 Java 資源的位置如下:
- java/
- resources/
- AndroidManifest.xml
- res/
- assets/
- aidl/
- rs/
- jni/
配置項目結構
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 到tests文件夾:
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')
}
}
注意: setRoot()會將整個sourceSet (和它的子文件夾) 移到一個新的文件夾中。這將移動src/androidTest/*到tests/*
下。這是 Android 專用的,不適用於 Java sourceSets。
這也是一個“遷移”的例子。
- assemble
組裝項目的輸出的任務 - check
運行所有檢查的任務。 - build
這個任務將執行assemble和check。 - clean
這個任務將清理項目的輸出
。
例如,配置使用findbugs插件將創建一個新的任務和使check任務依賴於它,使得每當調用check任務時都會調用到它。
您可以從命令行中運行下面的命令來獲取更高級別的任務:
gradle tasks
gradle tasks --all
在沒有變化的情況下,運行兩次build會使 Gradle 報告所有任務爲UP-TO-DATE狀態,這個狀態意味着沒有任何事情需要執行。這允許任務正確地相互依賴而無需不必要的構建操作。
- assemble
- jar
這個任務將創建輸出。
- jar
- check
- test
這個任務將運行測試。
- test
testClasses任務用於編譯測試,但它很少會被調用,因爲test任務依賴於它 (以及classes任務)。
一般情況下,你將可能永遠只調用assemble或check,而無視其他任務。
在這裏,你可以看到Java 插件的所有任務和對它們的描述。
Android 任務
- assemble
組裝項目的輸出的任務 - check
運行所有檢查的任務。 - connectedCheck
運行需要一個已連接的設備或模擬器的檢查。它們將在所有已連接的設備上並行運行。 - deviceCheck
使用 API 連接到遠程設備運行檢查。這一個是在 CI 服務器上使用的。 - build
這項任務將執行assemble 和 check - clean
這個任務將清理項目的輸出
注意到,build任務不依賴於deviceCheck或connectedCheck。
Android 項目具有至少兩個輸出: debug版本的APK 和release版本的 APK。這裏的每一個輸出都有自己的錨記任務,以便單獨構建它們:
- assemble
- assembleDebug
- assembleRelease
提示:在命令行上,Gradle 支持任務名稱的駝峯命名法的簡寫。例如:
gradle aR
gradle assembleRelease
check錨記任務有它們自己的依賴項:
- check
- lint
- connectedCheck
- connectedAndroidTest
- connectedUiAutomatorTest (暫未實現)
- deviceCheck
- 這個任務依賴於當其他插件實現了測試擴展點時創建的任務。
基本的構建定製
- minSdkVersion
- targetSdkVersion
- versionCode
- versionName
- applicationId (有效的包名 —— 更多的信息請參閱ApplicationId 與packageName)
- 用於測試應用程序的包名
- Instrumentation test runner
android {compileSdkVersion 19
buildToolsVersion "19.0.0"
defaultConfig {versionCode 12
versionName "2.0"
minSdkVersion 16
targetSdkVersion 16
}}
在android元素的內部的defaultConfig元素是定義所有這些配置的地方。
在構建文件中描述它的強大之處是它可以是動態的。
例如,可以從文件中的某處或使用一些自定義的邏輯讀取版本信息:
def computeVersionName() {...}android {compileSdkVersion 19buildToolsVersion "19.0.0"defaultConfig {versionCode 12versionName computeVersionName()
minSdkVersion 16
targetSdkVersion 16
}}
如果一個屬性未通過 DSL 來設置,它將使用默認值。下表描述了對於未設置的屬性的處理方式。
屬性名稱 | DSL 對象中的默認值 | 默認值 |
versionCode | -1 | 如果在清單中存在,則使用清單中的值 |
versionName | null | 如果在清單中存在,則使用清單中的值 |
minSdkVersion | -1 | 如果在清單中存在,則使用清單中的值 |
targetSdkVersion | -1 | 如果在清單中存在,則使用清單中的值 |
applicationId | null | 如果在清單中存在,則使用清單中的值 |
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...}
調試版本使用自動創建的密鑰/證書籤名,並且密鑰/證書的用戶名/密碼是已知的(以防止構建過程中需要相關的信息)的。release版本在構建的時候不會進行簽名,需要在之後進行簽名。
這個配置是通過一個叫BuildType的對象來完成的。默認情況下,2 個實例會被創建,分別是debug版和release版。
Android 插件允許自定義這兩個實例,以及創建其他的構建類型。它通過buildTypes DSL 容器來實現:
android {buildTypes {debug {applicationIdSuffix ".debug"
}jnidebug.initWith(buildTypes.debug)jnidebug {packageNameSuffix ".jnidebug"jniDebuggable true}}}
上面的代碼段可實現以下操作:
- 配置默認的Debug Build Type:
- 設置包名爲<app appliationId>.debug,以便能夠在相同的設備上安裝debug和release兩個版本的apk
- 創建一個叫jnidebug的新的BuildType對象 ,並將其配置爲debug生成類型的一個副本。
- 通過啓用 JNI 組件的debug構建,並添加不同的包後綴,繼續配置jnidebug。
以下是可能用到的屬性和它們的默認值:
屬性名稱 | 用於 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>/
與任何其他source set一樣,生成類型的source set的位置也是可以重新設置的:
android {sourceSets.jnidebug.setRoot('foo/jnidebug')}
已經提到過的assembleDebug和assembleRelease這兩個任務,這裏也會講一下它們是怎麼來的。當debug和releaseBuild Types被預創建的時候,他們的任務也會被自動創建。然後,
上面的build.gradle片段也會生成一個assembleJnidebug任務,並且assemble將會依賴於它,就像它依賴於assembleDebug和assembleRelease任務一樣。
提示: 請記住您可以輸入gradle aJ來運行assembleJnidebug任務。
可能會用到的情況:
- release模式下不需要,但debug模式下需要的權限
- 自定義的debug實現
- 爲調試模式使用不同的資源 (例如某個資源的值與簽名證書相綁定時)。
- manifest將被合併到應用程序的manifest中
- 代碼只是作爲另一個源文件夾來起作用
- 資源將覆蓋main裏面的資源,並替換已經存在的值。
簽名配置
- 一個 keystore
- 一個 keystore 的密碼
- 一個 key 的別名
- 一個 key 的密碼
- 存儲類型
默認情況下,有一個debug的配置,配置使用了一個debug keystore。這個keystore使用了一個已知的key和一個已知的密碼。
這個debug keystore 位於$HOME/.android/debug.keystore,並且會在不存在時被創建。debug Build Type被設置爲自動使用此debug
SigningConfig。
你也可以創建其他配置,或者自定義某個默認的內置配置。通過signingConfigs DSL 容器來實現:
android {signingConfigs {debug {storeFile file("debug.keystore")}myConfig {storeFile file("other.keystore")storePassword "android"keyAlias "androiddebugkey"keyPassword "android"}}buildTypes {foo {debuggable truejniDebuggable truesigningConfig signingConfigs.myConfig}}}
代碼的代碼還創建了一個新的Signing Config和使用新配置的新的Build Type 。
注:只有位於默認位置下的debug keystores纔會被自動創建。如果debug keystore的位置被更改了,它將不會在需要時自動創建。創建一個使用一個不同的名稱SigningConfig,但使用了默認的debug keystore的路徑,它也會被自動創建。換句話說,會不會被自動創建與keystore的路徑有關,而與配置名稱無關。
注: keystore的路徑通常使用項目根目錄的相對路徑,但也可以是使用絕對路徑,儘管這不推薦 (除了自動創建的debug keystore)。
運行ProGuard
buildTypes {
release {
minifyEnabled true
proguardFile getDefaultProguardFile('proguard-android.txt')
}
}
- proguard-android.txt
- proguard-android-optimize.txt