Android 建構系統會編譯應用程式資源和原始碼,並封裝至 APK 或 Android App Bundle,供您測試、部署、簽署及發布。
在「Gradle 建構總覽」和「Android 建構結構」一文中,我們討論了建構概念和 Android 應用程式的結構。現在,是時候設定建構作業了。
Android 建構詞彙表
Gradle 和 Android Gradle 外掛程式可協助您設定建構作業的下列切面:
- 建構類型
-
建構類型可定義 Gradle 在建構及封裝應用程式時採用的特定屬性,通常是針對開發生命週期的不同階段進行設定。
舉例來說,偵錯版本建構類型會啟用偵錯選項,並使用偵錯金鑰簽署應用程式;而發布版本建構類型可能會經過壓縮、混淆,並以發布金鑰簽署應用程式來以便發布。
您必須定義至少一個建構類型,才能建構應用程式。根據預設,Android Studio 會建立偵錯和發布這兩種建構類型。如要開始為應用程式自訂封裝設定,請瞭解如何設定建構類型。
- 變種版本
- 變種版本代表可向使用者發布的不同應用程式版本,例如免費版和付費版。您可運用不同的程式碼和資源來自訂變種版本,同時也能共用及重複使用所有應用程式版本之間通用的部分。您可以選擇是否提供變種版本,但必須手動建立這些版本。在開始建立應用程式的不同版本之前,請參閱「設定變種版本」一文。
- 建構變數
- 建構變數是結合建構類型和變種版本的產品,也是 Gradle 用於建構應用程式的設定。您可以使用建構變數,在開發期間建構變種版本的偵錯版本,以及用於發布的已簽署的變種版本。雖然您無法直接設定建構變數,但可以設定組成建構變數的建構類型和變種版本。建立其他建構類型或不同變種版本也會產生額外的建構變數。如要瞭解如何建立及管理建構變數,請參閱「設定建構變數」總覽。
- 資訊清單項目
- 您可以在設定產品建構變數時,指定資訊清單檔案中一部分屬性的數值。這些建構值會覆寫資訊清單檔案中原本的數值。如果要為應用程式產生多種變化版本,指定不同的應用程式名稱、最低 SDK 版本或目標 SDK 版本,這項功能就能派上用場。當同時存在多個資訊清單時,資訊清單合併工具會合併資訊清單設定。
- 依附元件
- 建構系統可管理來自本機檔案系統和遠端存放區的專案依附元件。也就是說,您不需要手動搜尋或下載依附元件的二進位套件,以及將套件複製到專案目錄中。詳情請參閱「新增建構依附元件」。
- 簽署
- 建構系統可讓您在建構設定中指定簽署設定,也能在建構程序期間自動簽署應用程式。建構系統會使用預設金鑰和憑證,以預設金鑰和憑證來簽署偵錯版本,避免在建構時發出密碼提示。除非您明確指定此建構作業的簽署方式,否則建構系統不會主動簽署發布版本。如果您沒有發布金鑰,可按照「簽署應用程式」中的說明產生金鑰。您必須使用經過簽署的發布版本,才能透過多數應用程式商店發布應用程式。
- 程式碼和資源縮減
- 您可以透過建構系統為每個建構變數指定不同的 ProGuard 規則檔案。建構應用程式時,建構系統會套用適當的規則組合,透過內建的縮減工具 (例如 R8) 縮減程式碼和資源。縮減程式碼和資源有助於縮減 APK 或 AAB 的大小。
- 支援多個 APK
- 建構系統可讓您自動建構不同的 APK,讓每個 APK 只包含特定螢幕密度或應用程式二進位檔介面 (ABI) 所需的程式碼和資源。詳情請參閱「 建構多個 APK」一文。不過,建議您採用發布單一 AAB 的做法,因為除了螢幕密度和 ABI 之外,此做法還能依據語言分割應用程式套件,同時降低將多個構件上傳至 Google Play 的必要性。2021 年 8 月後提交的所有新應用程式都必須使用 AAB。
Android 建構作業中的 Java 版本
無論原始碼是使用 Java、Kotlin 或兩者編寫,您都必須在幾個地方為建構作業選擇 JDK 或 Java 語言版本。詳情請參閱「Android 建構作業中的 Java 版本」。
建構設定檔
建立自訂建構設定時,您需要變更一或多個建構設定檔。這些純文字檔會使用領域特定語言 (DSL) 描述建構邏輯,並利用 Kotlin 指令碼加以操控。上述提及的 Kotlin 指令碼是 Kotlin 語言的變種版本。您也可以使用 Groovy,這是 Java 虛擬機器 (JVM 的動態語言) 的設定,
您不需要瞭解 Kotlin 指令碼或 Groovy 即可開始設定建構作業,因為 Android Gradle 外掛程式已提供需要使用的大多數 DSL 元素。如要進一步瞭解 Android Gradle 外掛程式 DSL,請參閱 DSL 參考說明文件。Kotlin 指令碼也需要使用基礎 Gradle Kotlin DSL
啟動新專案時,Android Studio 會自動為您建立一些檔案,並根據適當預設值填入資訊。如要瞭解建立的檔案,請參閱「Android 建構結構」。
Gradle 包裝函式檔案
Gradle 包裝函式 (gradlew
) 是包含在原始碼中的小型應用程式,會下載並啟動 Gradle 本身。這可讓建構執行作業更加一致。開發人員下載應用程式原始碼並執行 gradlew
。這會下載必要的 Gradle 發行版本,並啟動 Gradle 來建構應用程式。
gradle/wrapper/gradle-wrapper.properties
檔案包含屬性 distributionUrl
,用於說明要使用哪個版本的 Gradle 來執行建構作業。
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Gradle 設定檔
settings.gradle.kts
檔案 (適用於 Kotlin DSL) 或 settings.gradle
檔案 (適用於 Groovy DSL) 位於專案根目錄中。這個設定檔可定義專案層級的存放區設定,並告知 Gradle 應在建構應用程式時納入哪些模組。多模組專案必須指定應加入至最終版本的所有模組。
在大多數專案中,預設的檔案內容如下所示:
Kotlin
pluginManagement { /** * The pluginManagement.repositories block configures the * repositories Gradle uses to search or download the Gradle plugins and * their transitive dependencies. Gradle pre-configures support for remote * repositories such as JCenter, Maven Central, and Ivy. You can also use * local repositories or define your own remote repositories. Here we * define the Gradle Plugin Portal, Google's Maven repository, * and the Maven Central Repository as the repositories Gradle should use to look for its * dependencies. */ repositories { gradlePluginPortal() google() mavenCentral() } } dependencyResolutionManagement { /** * The dependencyResolutionManagement.repositories * block is where you configure the repositories and dependencies used by * all modules in your project, such as libraries that you are using to * create your application. However, you should configure module-specific * dependencies in each module-level build.gradle file. For new projects, * Android Studio includes Google's Maven repository and the Maven Central * Repository by default, but it does not configure any dependencies (unless * you select a template that requires some). */ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } } rootProject.name = "My Application" include(":app")
Groovy
pluginManagement { /** * The pluginManagement.repositories block configures the * repositories Gradle uses to search or download the Gradle plugins and * their transitive dependencies. Gradle pre-configures support for remote * repositories such as JCenter, Maven Central, and Ivy. You can also use * local repositories or define your own remote repositories. Here we * define the Gradle Plugin Portal, Google's Maven repository, * and the Maven Central Repository as the repositories Gradle should use to look for its * dependencies. */ repositories { gradlePluginPortal() google() mavenCentral() } } dependencyResolutionManagement { /** * The dependencyResolutionManagement.repositories * block is where you configure the repositories and dependencies used by * all modules in your project, such as libraries that you are using to * create your application. However, you should configure module-specific * dependencies in each module-level build.gradle file. For new projects, * Android Studio includes Google's Maven repository and the Maven Central * Repository by default, but it does not configure any dependencies (unless * you select a template that requires some). */ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } } rootProject.name = "My Application" include ':app'
頂層建構檔案
頂層 build.gradle.kts
檔案 (適用於 Kotlin DSL) 或 build.gradle
檔案 (適用於 Groovy DSL) 位於專案根目錄中,通常會定義專案中模組使用的常見外掛程式版本。
以下程式碼範例說明建立新專案後,頂層建構指令碼中的預設設定和 DSL 元素:
Kotlin
plugins { /** * Use `apply false` in the top-level build.gradle file to add a Gradle * plugin as a build dependency but not apply it to the current (root) * project. Don't use `apply false` in sub-projects. For more information, * see Applying external plugins with same version to subprojects. */ id("com.android.application") version "8.7.0" apply false id("com.android.library") version "8.7.0" apply false id("org.jetbrains.kotlin.android") version "2.0.20" apply false }
Groovy
plugins { /** * Use `apply false` in the top-level build.gradle file to add a Gradle * plugin as a build dependency but not apply it to the current (root) * project. Don't use `apply false` in sub-projects. For more information, * see Applying external plugins with same version to subprojects. */ id 'com.android.application' version '8.7.0' apply false id 'com.android.library' version '8.7.0' apply false id 'org.jetbrains.kotlin.android' version '2.0.20' apply false }
模組層級建構檔案
模組層級 build.gradle.kts
(適用於 Kotlin DSL) 或 build.gradle
檔案 (適用於 Groovy DSL) 位於各個 project/module/
目錄中,可讓您對其所在的特定模組調整建構設定。調整這些建構設定可讓您提供自訂封裝選項,例如額外的建構類型和變種版本,並可覆寫 main/
應用程式資訊清單或頂層建構指令碼中的設定。
Android SDK 設定
應用程式的模組層級建構檔案包含相關設定,用於指定編譯時使用的 Android SDK 版本、選取平台行為,以及指定執行應用程式的最低版本。
-
compileSdk
-
compileSdk
會決定編譯原始碼時可用的 Android 和 Java API。如要使用最新的 Android 功能,請在編譯時使用最新的 Android SDK。部分 Android 平台 API 可能不適用於舊版 API 級別。您可以 有條件地控管新功能的使用,或透過 AndroidX 相容性程式庫使用 Android API 級別較低的新功能。
每個 Android SDK 都會提供一組 Java API,供您在應用程式中使用。如要瞭解可在 Java 或 Kotlin 原始碼中使用的 Java API,請參閱「我可以在 Java 或 Kotlin 原始碼中使用哪些 Java API」一文中的表格,瞭解可用的 Java API 級別。較新的 Java API 可透過脫糖在較舊的 Android 版本中支援,但您必須在建構作業中啟用這項功能。
如果
compileSdk
與目前的 Android Studio、AGP 版本或專案的程式庫依附元件要求發生衝突,Android Studio 會顯示警告。 -
minSdk
-
minSdk
會指定應用程式支援的最低 Android 版本。設定minSdk
可限制哪些裝置可以安裝您的應用程式。如要支援較低版本的 Android,可能需要在程式碼中進行更多條件檢查,或使用 AndroidX 相容性程式庫。您應權衡支援較舊版本的維護成本,並評估仍在使用這些舊版本的使用者百分比。如要查看目前版本使用百分比,請參閱 Android Studio 新專案精靈中的版本圖表。
在 Android Studio 中編輯程式碼或在建構期間執行檢查時,Lint 會針對你使用的 API 發出警示,指出
minSdk
中未提供的 API。您應透過 將新功能設為條件式或使用Appcompat
來修正這些問題,以便回溯相容性。 -
targetSdk
-
targetSdk
有兩個用途:- 它會設定應用程式的執行階段行為。
- 用於證明你已通過測試的 Android 版本。
如果您在使用比
targetSdk
更高版本 Android 的裝置上執行應用程式,Android 會在相容性模式下執行應用程式,其行為類似於targetSdk
中所指示的較低版本。舉例來說,API 23 導入了執行階段權限模型時,並非所有應用程式都能立即採用。將targetSdk
設為 22 後,這些應用程式就能在 API 23 裝置上執行,且無須使用執行階段權限,還能使用最新compileSdk
版本中的功能。Google Play 發布政策會強制執行目標 API 級別的其他政策。targetSdk
的值必須小於或等於compileSdk
。
注意:compileSdk
和 targetSdk
的值不必相同。請留意下列基本原則:
compileSdk
可讓您存取新的 APItargetSdk
會設定應用程式的執行階段行為targetSdk
必須小於或等於compileSdk
應用程式模組建構指令碼範例
以下的 Android 應用程式模組建構指令碼範例,概要說明部分基本的 DSL 元素和設定:
Kotlin
/** * The first section in the build configuration applies the Android Gradle plugin * to this build and makes the android block available to specify * Android-specific build options. */ plugins { id("com.android.application") } /** * Locate (and possibly download) a JDK used to build your kotlin * source code. This also acts as a default for sourceCompatibility, * targetCompatibility and jvmTarget. Note that this does not affect which JDK * is used to run the Gradle build itself, and does not need to take into * account the JDK version required by Gradle plugins (such as the * Android Gradle Plugin) */ kotlin { jvmToolchain(11) } /** * The android block is where you configure all your Android-specific * build options. */ android { /** * The app's namespace. Used primarily to access app resources. */ namespace = "com.example.myapp" /** * compileSdk specifies the Android API level Gradle should use to * compile your app. This means your app can use the API features included in * this API level and lower. */ compileSdk = 33 /** * The defaultConfig block encapsulates default settings and entries for all * build variants and can override some attributes in main/AndroidManifest.xml * dynamically from the build system. You can configure product flavors to override * these values for different versions of your app. */ defaultConfig { // Uniquely identifies the package for publishing. applicationId = "com.example.myapp" // Defines the minimum API level required to run the app. minSdk = 21 // Specifies the API level used to test the app. targetSdk = 33 // Defines the version number of your app. versionCode = 1 // Defines a user-friendly version name for your app. versionName = "1.0" } /** * The buildTypes block is where you can configure multiple build types. * By default, the build system defines two build types: debug and release. The * debug build type is not explicitly shown in the default build configuration, * but it includes debugging tools and is signed with the debug key. The release * build type applies ProGuard settings and is not signed by default. */ buildTypes { /** * By default, Android Studio configures the release build type to enable code * shrinking, using minifyEnabled, and specifies the default ProGuard rules file. */ getByName("release") { isMinifyEnabled = true // Enables code shrinking for the release build type. proguardFiles( getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" ) } } /** * The productFlavors block is where you can configure multiple product flavors. * This lets you create different versions of your app that can * override the defaultConfig block with their own settings. Product flavors * are optional, and the build system does not create them by default. * * This example creates a free and paid product flavor. Each product flavor * then specifies its own application ID, so that they can exist on the Google * Play Store or an Android device simultaneously. * * If you declare product flavors, you must also declare flavor dimensions * and assign each flavor to a flavor dimension. */ flavorDimensions += "tier" productFlavors { create("free") { dimension = "tier" applicationId = "com.example.myapp.free" } create("paid") { dimension = "tier" applicationId = "com.example.myapp.paid" } } /** * To override source and target compatibility (if different from the * toolchain JDK version), add the following. All of these * default to the same value as kotlin.jvmToolchain. If you're using the * same version for these values and kotlin.jvmToolchain, you can * remove these blocks. */ //compileOptions { // sourceCompatibility = JavaVersion.VERSION_11 // targetCompatibility = JavaVersion.VERSION_11 //} //kotlinOptions { // jvmTarget = "11" //} } /** * The dependencies block in the module-level build configuration file * specifies dependencies required to build only the module itself. * To learn more, go to Add build dependencies. */ dependencies { implementation(project(":lib")) implementation("androidx.appcompat:appcompat:1.7.0") implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) }
Groovy
/** * The first line in the build configuration applies the Android Gradle plugin * to this build and makes the android block available to specify * Android-specific build options. */ plugins { id 'com.android.application' } /** * Locate (and possibly download) a JDK used to build your kotlin * source code. This also acts as a default for sourceCompatibility, * targetCompatibility and jvmTarget. Note that this does not affect which JDK * is used to run the Gradle build itself, and does not need to take into * account the JDK version required by Gradle plugins (such as the * Android Gradle Plugin) */ kotlin { jvmToolchain 11 } /** * The android block is where you configure all your Android-specific * build options. */ android { /** * The app's namespace. Used primarily to access app resources. */ namespace 'com.example.myapp' /** * compileSdk specifies the Android API level Gradle should use to * compile your app. This means your app can use the API features included in * this API level and lower. */ compileSdk 33 /** * The defaultConfig block encapsulates default settings and entries for all * build variants and can override some attributes in main/AndroidManifest.xml * dynamically from the build system. You can configure product flavors to override * these values for different versions of your app. */ defaultConfig { // Uniquely identifies the package for publishing. applicationId 'com.example.myapp' // Defines the minimum API level required to run the app. minSdk 21 // Specifies the API level used to test the app. targetSdk 33 // Defines the version number of your app. versionCode 1 // Defines a user-friendly version name for your app. versionName "1.0" } /** * The buildTypes block is where you can configure multiple build types. * By default, the build system defines two build types: debug and release. The * debug build type is not explicitly shown in the default build configuration, * but it includes debugging tools and is signed with the debug key. The release * build type applies ProGuard settings and is not signed by default. */ buildTypes { /** * By default, Android Studio configures the release build type to enable code * shrinking, using minifyEnabled, and specifies the default ProGuard rules file. */ release { minifyEnabled true // Enables code shrinking for the release build type. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } /** * The productFlavors block is where you can configure multiple product flavors. * This lets you create different versions of your app that can * override the defaultConfig block with their own settings. Product flavors * are optional, and the build system does not create them by default. * * This example creates a free and paid product flavor. Each product flavor * then specifies its own application ID, so that they can exist on the Google * Play Store or an Android device simultaneously. * * If you declare product flavors, you must also declare flavor dimensions * and assign each flavor to a flavor dimension. */ flavorDimensions "tier" productFlavors { free { dimension "tier" applicationId 'com.example.myapp.free' } paid { dimension "tier" applicationId 'com.example.myapp.paid' } } /** * To override source and target compatibility (if different from the * tool chain JDK version), add the following. All of these * default to the same value as kotlin.jvmToolchain. If you're using the * same version for these values and kotlin.jvmToolchain, you can * remove these blocks. */ //compileOptions { // sourceCompatibility JavaVersion.VERSION_11 // targetCompatibility JavaVersion.VERSION_11 //} //kotlinOptions { // jvmTarget = '11' //} } /** * The dependencies block in the module-level build configuration file * specifies dependencies required to build only the module itself. * To learn more, go to Add build dependencies. */ dependencies { implementation project(":lib") implementation 'androidx.appcompat:appcompat:1.7.0' implementation fileTree(dir: 'libs', include: ['*.jar']) }
Gradle 屬性檔案
Gradle 也包含兩個位於專案根目錄中的屬性檔案,可用來指定 Gradle 建構工具包本身的設定:
-
gradle.properties
- 您可以在此設定專案層級的 Gradle 設定,例如 Gradle Daemon 的最大堆積大小。詳情請參閱「建構環境」。
-
local.properties
-
設定建構系統的本地環境屬性,包括:
ndk.dir
- 到 NDK 的路徑。此屬性已淘汰。任何下載的 NDK 版本都會安裝在 Android SDK 目錄的ndk
目錄中。sdk.dir
- Android SDK 的路徑。cmake.dir
- 到 CMake 的路徑。ndk.symlinkdir
- 在 Android Studio 3.5 以上版本中建立 NDK 的符號連結,比起已安裝的 NDK 路徑,這類連結可能會較短。
將 NDK 重新映射到較短的路徑 (僅限 Windows)
在 Windows 中,已安裝 NDK 資料夾中的工具 (例如 ld.exe
) 會產生長路徑。這些工具無法妥善支援長路徑。
如要建立較短的路徑,請在 local.properties
中設定 ndk.symlinkdir
屬性,要求 Android Gradle 外掛程式建立指向 NDK 的符號連結。該符號連結的路徑可能會比現有 NDK 資料夾的路徑短。舉例來說,ndk.symlinkdir = C:\
會產生以下符號連結:C:\ndk\19.0.5232133
將專案與 Gradle 檔案同步處理
當您變更專案中的建構設定檔時,Android Studio 會要求您同步處理專案檔案,以便匯入建構設定變更,並執行相關檢查,確認您的設定不會發生建構錯誤。
如要同步處理專案檔案,請在進行變更後顯示的通知列中按一下「Sync Now」(如圖 2 所示),或按一下選單列中的「Sync Project」圖示 。如果 Android Studio 發現您的設定有誤,例如原始碼使用了只會在 compileSdkVersion
以上的 API 級別中提供的 API 功能,就會透過「Messages」視窗說明問題。
來源集
Android Studio 會按照邏輯將所有模組的原始碼和資源歸類為多個來源集。當您建立新模組時,Android Studio 會在模組內建立 main/
來源集。模組的 main/
來源集包含其所有建構變數使用的程式碼和資源。
其他來源集目錄為選用性質,因此當您設定新的建構變數時,Android Studio 不會自動建立這些目錄。然而,建立類似於 main/
的來源集有助於管理 Gradle 僅在建構特定應用程式版本時才會使用的檔案和資源:
-
src/main/
- 此來源集包含所有建構變數共用的程式碼和資源。
-
src/buildType/
- 建立此來源集,以便納入特定建構類型的程式碼和資源。
-
src/productFlavor/
- 建立此來源集,納入僅用於特定變種版本的程式碼和資源。
注意:如果您將建構設定調整為合併多個變種版本,則可以在不同版本維度之間為每個變種版本組合建立來源集目錄:
src/productFlavor1ProductFlavor2/
。 -
src/productFlavorBuildType/
- 建立此來源集,以便納入特定建構變數的程式碼和資源。
舉例來說,如要產生應用程式的「fullDebug」版本,建構系統將會合併下列來源集的程式碼、設定和資源:
-
src/fullDebug/
(建構變化版本來源集) -
src/debug/
(建構類型來源集) -
src/full/
(變種版本來源集) -
src/main/
(主要來源集)
注意:在 Android Studio 中新建檔案或目錄時,請依序點選「File」>「New」選單選項,為特定來源集建立檔案或目錄。您可選擇的來源集取決於您的建構設定。如果所需的目錄不存在,Android Studio 就會自動建立。
如果不同的來源集包含相同檔案的不同版本,Gradle 會按照下列優先順序決定要使用的檔案。左側來源集會覆寫右側來源集的檔案和設定:
建構變數 > 建構類型 > 變種版本 > 主要來源集 > 程式庫依附元件
這樣一來,Gradle 就能按照您要建立的建構變化版本選擇專用的檔案,同時重複使用其他應用程式版本常見的活動、應用程式邏輯和資源。
合併多個資訊清單時,Gradle 會使用相同的優先順序,因此每個建構變數都能在最終資訊清單中定義不同的元件或權限。如要進一步瞭解如何建立自訂來源集,請參閱「建立來源集」相關說明。
版本目錄
如果您的建構內容包含多個含有常用依附元件的模組,或是您有多個含有常用依附元件的獨立專案,建議您使用版本目錄或物料清單 (BoM) 指定常用版本。
其他建構系統
您可以使用 Bazel 建構 Android 應用程式,但系統並未正式提供支援。Android Studio 並未正式支援 Bazel 專案。
如要進一步瞭解使用 Bazel 進行建構的目前限制,請參閱已知問題。