# 操作 task
一般的 Java 項目中有一組有限的 task 用于互相處理并最終生成一個輸出。
**classes** 是一個編譯 Java 源代碼的 task。
可以在 *build.gradle* 文件中通過腳本很容易使用 **classes** task。**classes** 是 **project.tasks.classes** 的縮寫。
相比之下在 Android 項目中這就有點復雜。因為 Android 項目中會有大量相同的 task,并且它們的名字基于 *Build Types* 和 *Product Flavor* 生成。
為了解決這個問題,**android** 對象有三個屬性:
- **applicationVariants**(只適用于 app plugin)
- **libraryVariants**(只適用于 library plugin)
- **testVariants**(app、library plugin 均適用)
這三個屬性會分別返回一個 `ApplicationVariant`、`LibraryVariant` 和 `TestVariant` 對象的 [DomainObjectCollection](http://www.gradle.org/docs/current/javadoc/org/gradle/api/DomainObjectCollection.html)。
注意,使用這三個 collection 中的其中一個都會觸發生成所有對應的 task。這意味著使用 collection 之后不需要更改配置。
`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 的 task |
| aidlCompile | AidlCompile | 編譯 AIDL 文件的 task |
| renderscriptCompile | RenderscriptCompile | 編譯 Renderscript 文件的 task |
| mergeResources | MergeResources | 合并資源文件的 task |
| mergeAssets | MergeAssets | 合并 assets 的 task |
| processResources | ProcessAndroidResources | 處理并編譯資源文件的 task |
| generateBuildConfig | GenerateBuildConfig | 生成 BuildConfig 類的 task |
| javaCompile | JavaCompile | 編譯 Java 源代碼的 task |
| processJavaResources | Copy | 處理 Java 資源的 task |
| assemble | DefaultTask | Variant 的標志性 assemble task |
`ApplicationVariant` 類還有以下附加屬性:
| 屬性名 | 屬性類型 | 說明 |
|-----|-----|-----|
| buildType | BuildType | Variant 的 BuildType |
| productFlavors | List<ProductFlavor> | Variant 的 ProductFlavor,一般不為空但允許為空 |
| mergedFlavor | ProductFlavor | android.defaultConfig 和 variant.productFlavors 的組合 |
| signingConfig | SigningConfig | Variant 使用的 SigningConfig 對象 |
| isSigningReady | boolean | 如果是 true 則表明該 Variant 已經具備了所有需要簽名的信息 |
| testVariant | BuildVariant | 將會測試該 Variant 的 TestVariant |
| dex | Dex | 將代碼打包成 dex 的 task。如果該 Variant 是 Library,該值可為空 |
| packageApplication | PackageApplication | 打包最終 APK 的 task。如果該 Variant 是 Library,該值可為空 |
| zipAlign | ZipAlign | 對 APK 進行 zipalign 的 task。如果該 Variant 是 Library 或者 APK 不能被簽名時,該值可為空 |
| install | DefaultTask | 負責安裝的 task,可為空 |
| uninstall | DefaultTask | 負責卸載的 task |
`LibraryVariant` 類還有以下附加屬性:
| 屬性名 | 屬性類型 | 說明 |
|-----|-----|-----|
| buildType | BuildType | Variant 的 BuildType |
| mergedFlavor | ProductFlavor | 只有 android.defaultConfig |
| testVariant | BuildVariant | 用于測試 Variant |
| packageLibrary | Zip | 用于打包 Library 項目的 AAR 文件。如果是 Library 項目,該值不能為空 |
`TestVariant` 類還有以下屬性:
| 屬性名 | 屬性類型 | 說明 |
|-----|-----|-----|
| buildType | BuildType | Variant 的 Build Type |
| productFlavors | List<ProductFlavor> | Variant 的 ProductFlavor。一般不為空但允許為空 |
| mergedFlavor | ProductFlavor | android.defaultConfig 和 variant.productFlavors 的組合 |
| signingConfig | SigningConfig | Variant 使用的 SigningConfig 對象 |
| isSigningReady | boolean | 如果是 true 則表明該 Variant 已經具備了所有需要簽名的信息 |
| testedVariant | BaseVariant | TestVariant 測試的 BaseVariant |
| dex | Dex | 將代碼打包成 dex 的 task。如果該 Variant 是 Library,該值可為空 |
| packageApplication | PackageApplication | 打包最終 APK 的 task。如果該 Variant 是 Library,該值可為空 |
| zipAlign | ZipAlign | 對 APK 進行 zipalign 的 task。如果該 Variant 是 Library 或者 APK 不能被簽名時,該值可為空 |
| install | DefaultTask | 負責安裝的 task,可為空 |
| uninstall | DefaultTask | 負責卸載的 task |
| connectedAndroidTest | DefaultTask | 在連接設備上執行 Android 測試的 task |
| providerAndroidTest | DefaultTask | 使用擴展 API 執行 Android 測試的 task |
Android task 特有類型的 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`
- 直接在 Variant 對象中使用 “outputFile” 可以改變最終的輸出文件夾。
- `ZipAlign`
- `File inputFile`
- `File outputFile`
- 直接在 Variant 對象中使用 “outputFile” 可以改變最終的輸出文件夾。
每個 task 類型的 API 都受 Gradle 的工作方式和 Android plugin 的配置方式限制。
首先,Gradle 中存在的 task 只能配置輸入輸出的路徑以及部分可能使用的選項標識。因此,task 只能定義一些輸入或者輸出。
其次,這里面大多數 task 的輸入都不是單一的,一般都混合了 *sourceSet*、*Build Type* 和 *Product Flavor* 中的值。保持構建文件的簡潔和可讀性,同時讓開發者通過 DSL 修改這些對象來影響構建的過程,而不是深入修改輸入和 task 的選項。
另外需要注意,上面的 task 中除了 ZipAlign 這個 task 類型,其它類型都要求設置私有數據來讓它們運行。這意味著不能手動創建這些類型的新 task 實例。
這些 API 也可能會被修改。一般來說,目前的 API 是圍繞著 task 的輸入和輸出入口來添加額外的處理(需要的時候)。歡迎反饋意見,特別是那些沒有預見過的需求。
對于 Gradle 的 task(DefaultTask,JavaCompile,Copy,Zip),請參考 Gradle 文檔。
- 譯者序
- 簡介
- 新構建系統的目標
- 為什么使用 Gradle?
- 配置要求
- 基礎項目
- 構建文件示例
- 項目結構
- 配置項目結構
- 構建任務
- 通用任務
- Java 項目的 Task
- Android Tasks
- 基本的構建定制
- Manifest 屬性
- 構建類型
- 簽名配置
- 運行 ProGuard
- 清理資源
- 依賴、Library 和多項目
- 包依賴
- 本地包依賴
- 遠程包依賴
- 多項目設置
- Library 項目
- 創建 Library 項目
- 普通項目和 Library 項目的區別
- 引用 Library 項目
- Library 項目發布
- 測試
- 單元測試
- 基本知識和配置
- 運行測試
- 測試 Android Library 項目
- 測試報告
- 獨立項目
- 多項目報告
- Lint 支持
- 構建 Variants(變種)版本
- 產品定制
- 構建類型+產品定制=構建變種版本
- 產品定制的配置
- 源組件和依賴
- 構建和任務
- 測試
- 多定制的變種版本
- 高級構建的自定義
- 構建選項
- Java 編譯選項
- aapt 選項
- dex 選項
- 操作 task
- 構建類型和產物定制的屬性引用
- 使用sourceCompatibility 1.7
- 附錄
- ApplicationId 與 packageName