建構設定

Android 建構系統會編譯應用程式資源和原始碼,並封裝至 APK 或 Android App Bundle,供您測試、部署、簽署及發布。

Android Studio 會使用進階建構工具包 Gradle 自動執行及管理建構程序,可讓您靈活定義自訂建構設定。每項建構設定都能定義其專屬的程式碼和資源組合,同時也能重複使用應用程式所有版本共用的部分。Android Gradle 外掛程式可與建構工具包搭配運作,提供專門用於建構及測試 Android 應用程式的處理程序和可調整設定。

Gradle 和 Android Gradle 外掛程式會獨立於 Android Studio 之外執行。也就是說,您可以從 Android Studio 內部、電腦上的指令列或未安裝 Android Studio 的電腦 (例如持續整合伺服器),建構 Android 應用程式。

如果您未使用 Android Studio,建議您瞭解如何透過指令列建構及執行應用程式。建構作業的輸出內容不會因為透過指令列、遠端電腦或 Android Studio 建構專案而有所差異。

注意:由於 Gradle 和 Android Gradle 外掛程式是獨立於 Android Studio 之外執行,因此您必須分別更新建構工具。請參閱版本資訊,瞭解如何更新 Gradle 和 Android Gradle 外掛程式

使用靈活的 Android 建構系統,您無須修改應用程式的核心來源檔案,即可建立自訂建構設定。本頁內容將帶您瞭解 Android 建構系統的運作方式,以及該系統如何協助您自訂及自動執行多項建構設定。如要進一步瞭解如何部署應用程式,請參閱「建構並執行應用程式」一文。如果想立即使用 Android Studio 建立自訂建構設定,請參閱「設定建構變數」一文。

建構程序

建構程序牽涉到許多工具和程序的運作,這些工具和程序會將專案轉換為 Android 應用程式套件 (APK) 或 Android App Bundle (AAB)。

Android Gradle 外掛程式會為您執行大部分的建構程序,但瞭解建構程序的特定切面,有助您根據需求調整建構作業。

不同專案的建構目標也會有所差異。例如,第三方程式庫的建構作業會產生 AAR 或 JAR 程式庫。不過,應用程式是最常見的專案類型,應用程式專案的建構作業會產生用於偵錯或發布的應用程式 APK 或 AAB,供您部署、測試或發布給外部使用者。

儘管本頁重點在於應用程式開發,但其中許多建構步驟和概念皆常見於多數建構類型。

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。

建構設定檔

建立自訂建構設定時,您需要變更一或多個建構設定檔或 build.gradle 檔案。這些純文字檔會使用領域特定語言 (DSL) 描述建構邏輯,並利用 GroovyKotlin 指令碼加以操控。上述提及的 Groovy 是 Java 虛擬機器 (JVM) 的動態語言,而 Kotlin 指令碼則是 Kotlin 語言的變種版本。

您不需要瞭解 Groovy 或 Kotlin 指令碼即可開始設定建構作業,因為 Android Gradle 外掛程式已提供需要使用的大多數 DSL 元素。如要進一步瞭解 Android Gradle 外掛程式 DSL,請參閱 Groovy 的 DSL 參考說明文件。Kotlin 指令碼也需要使用基礎 Gradle Kotlin DSL

啟動新專案時,Android Studio 會自動為您建立一些檔案 (如圖 1 所示),並根據適當預設值填入資訊。

圖 1 Android 應用程式模組的預設專案結構。

有些 Gradle 建構設定檔是 Android 應用程式標準專案結構的一部分。因此,在開始設定建構作業之前,請務必先瞭解相關檔案的適用範圍與目的,以及其所定義的 DSL 基本元素。

Gradle 設定檔

settings.gradle 檔案 (適用於 Groovy) 或 settings.gradle.kts 檔案 (適用於 Kotlin 指令碼) 位於專案根目錄中。這個設定檔可定義專案層級的存放區設定,並告知 Gradle 應在建構應用程式時納入哪些模組。多模組專案必須指定應加入至最終版本的所有模組。

在大多數專案中,預設的檔案內容如下所示:

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. The code below
     * defines 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’

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. The code below
     * defines 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 檔案 (適用於 Groovy) 或 build.gradle.kts 檔案 (適用於 Kotlin 指令碼) 位於專案根目錄中,可定義適用於專案中所有模組的依附元件。根據預設,頂層建構檔案會使用 plugins 區塊,定義專案中所有模組共用的 Gradle 依附元件。此外,頂層建構檔案也包含負責清除建構目錄的程式碼。

以下程式碼範例說明建立新專案後,頂層 build.gradle 檔案中的預設設定和 DSL 元素:

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 '7.4.1' apply false
    id 'com.android.library' version '7.4.1' apply false
    id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
}

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 "7.4.1" apply false
    id("com.android.library") version "7.4.1" apply false
    id("org.jetbrains.kotlin.android") version "1.8.10" apply false
}

使用額外屬性設定全專案的屬性 (已淘汰)

針對包含多個模組的 Android 專案,您可以在專案層級定義特定屬性,並與所有模組共用這些屬性,這個做法可能大有用處。只要在頂層 build.gradle 檔案 (適用於 Groovy) 或 build.gradle.kts 檔案 (適用於 Kotlin 指令碼) 的 ext 區塊中加入額外屬性即可。

Groovy

// This block encapsulates custom properties and makes them available to all
// modules in the project. The following are only a few examples of the types
// of properties you can define.
ext {
    sdkVersion = 33
    // You can also create properties to specify versions for dependencies.
    // Having consistent versions between modules can avoid conflicts with behavior.
    appcompatVersion = "1.6.1"
    ...
}
...

Kotlin

// This block encapsulates custom properties and makes them available to all
// modules in the project. The following are only a few examples of the types
// of properties you can define.
ext {
    extra["sdkVersion"] = 33
    // You can also create properties to specify versions for dependencies.
    // Having consistent versions between modules can avoid conflicts with behavior.
    extra["appcompatVersion"] = "1.6.1"
    ...
}
...

如要從相同專案中的模組存取這些屬性,請在模組的 build.gradle 檔案中使用以下語法。

Groovy

android {
    // Use the following syntax to access properties you defined at the project level:
    // rootProject.ext.property_name
    compileSdk rootProject.ext.sdkVersion
    ...
}
...
dependencies {
    implementation "androidx.appcompat:appcompat:${rootProject.ext.appcompatVersion}"
    ...
}

Kotlin

android {
    // Use the following syntax to access properties you defined at the project level:
    // rootProject.extra["property_name"]
    compileSdk = rootProject.extra["sdkVersion"]

    // Alternatively, you can access properties using a type safe delegate:
    val sdkVersion: Int by rootProject.extra
    ...
    compileSdk = sdkVersion
}
...
dependencies {
    implementation("androidx.appcompat:appcompat:${rootProject.ext.appcompatVersion}")
    ...
}

模組層級建構檔案

模組層級 build.gradle 檔案 (適用於 Groovy) 或 build.gradle.kts (適用於 Kotlin 指令碼) 位於各個 project/module/ 目錄中,可讓您對其所在的特定模組調整建構設定。調整相關建構設定可讓您提供自訂封裝選項,例如額外的建構類型和變種版本,並可覆寫 main/ 應用程式資訊清單或頂層 build.gradle/build.gradle.kts 檔案中的相關設定。

以下的 Android 應用程式模組 build.gradle 檔案範例,概要說明部分基本的 DSL 元素和設定:

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'
}

/**
 * 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'
        }
    }
}

/**
 * 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.6.1'
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

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")
}

/**
 * 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"
        }
    }
}

/**
 * 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.6.1")
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Gradle 屬性檔案

Gradle 也包含兩個位於專案根目錄中的屬性檔案,可用來指定 Gradle 建構工具包本身的設定:

gradle.properties
您可以在這裡調整專案層級的 Gradle 設定,例如 Gradle Daemon 的堆積大小上限。詳情請參閱「建構環境」一文。
local.properties
設定建構系統的本機環境屬性,包括:
  • ndk.dir - 到 NDK 的路徑。這項屬性已淘汰。任何下載的 NDK 版本都會安裝在 Android SDK 目錄的 ndk 目錄中。
  • sdk.dir - 指向 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」視窗說明問題。

圖 2 在 Android Studio 中將專案與建構設定檔同步處理。

來源集

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 會使用相同的優先順序,因此每個建構變數都能在最終資訊清單中定義不同的元件或權限。如要進一步瞭解如何建立自訂來源集,請參閱「建立來源集」相關說明。

其他建構系統

您可以使用 Bazel 建構 Android 應用程式,但系統並未正式提供支援。Android Studio 並未正式支援 Bazel 專案。

如要進一步瞭解使用 Bazel 進行建構的目前限制,請參閱已知問題