一般的 Java 項目中有一組 task 用於協同處理並最終生成一個輸出。
classes task 用於編譯 Java 源代碼。
可以在 build.gradle 文件中使用 classes 訪問 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。
注意,使用這三個 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:
ProcessManifestFile manifestOutputFile
AidlCompileFile sourceOutputDir
RenderscriptCompileFile sourceOutputDirFile resOutputDir
MergeResourcesFile outputDir
MergeAssetsFile outputDir
ProcessAndroidResourcesFile manifestFileFile resDirFile assetsDirFile sourceOutputDirFile textSymbolOutputDirFile packageOutputFileFile proguardOutputFile
GenerateBuildConfigFile sourceOutputDir
DexFile outputFolder
PackageApplicationFile resourceFileFile dexFileFile javaResourceDirFile jniDirFile outputFile- 直接在 Variant 對象中使用 “outputFile” 可以改變最終的輸出文件夾。
ZipAlignFile inputFileFile outputFile- 直接在 Variant 對象中使用 “outputFile” 可以改變最終的輸出文件夾。
每個 task 類型的 API 都受 Gradle 的工作方式和 Android plugin 的配置方式限制。
首先,Gradle 中存在的 task 只能配置輸入輸出的路徑以及部分可能使用的可選標識。因此,這些 task 只能定義一些輸入或者輸出。
其次,這里面大多數 task 的輸入都不是單一的,一般都混合了 sourceSet、Build Type 和 Product Flavor 中的值。所以為了保持構建文件的簡潔和可讀性,目標自然是讓開發者通過 DSL 修改這些對象來影響構建的過程,而不是深入修改輸入和 task 的選項。
另外需要注意,上面的 task 中除了 ZipAlign,其它都要求設置私有數據進行工作。這意味着不能手動創建這些類型的 task 實例。
這些 API 也可能會被修改。一般來說,目前的 API 是圍繞着 task 的輸出和輸入(如果可能)來添加額外的處理(必要時)。歡迎反饋意見,特別是那些沒有考慮過的需求。
對於 Gradle 的 task(DefaultTask,JavaCompile,Copy,Zip),請參考 Gradle 文檔。
