配置 build

Android 构建系统会编译应用资源和源代码,然后将它们打包成 APK 或 Android App Bundle 文件,供您测试、部署、签名和分发。

Android Studio 使用高级构建工具包 Gradle 来自动执行和管理构建流程,同时也允许您自行指定灵活的 build 配置。每项 build 配置均可定义各自的一组代码和资源,同时重复利用所有应用版本共用的部分。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 构建系统非常灵活,让您可以在不修改应用核心源代码文件的情况下创建自定义的 build 配置。本页介绍了 Android 构建系统的工作原理,以及它如何帮助您对多项 build 配置进行自定义和自动化处理。如需详细了解如何部署应用,请参阅构建和运行应用。如要立即开始使用 Android Studio 创建自定义 build 配置,请参阅配置 build 变体

构建流程

构建流程涉及许多将项目转换成 Android 应用软件包 (APK) 或 Android App Bundle (AAB) 文件的工具和流程。

Android Gradle 插件可以为您完成构建流程的大部分工作,但了解构建流程的某些方面会很有用,有助于您根据需要调整 build。

不同的项目可能具有不同的构建目标。例如,针对第三方库的 build 会生成 AAR 或 JAR 库。 不过,应用是最常见的项目类型,而应用项目的 build 会生成应用的调试版或者发布版 APK 或 AAB,以用于部署、测试或向外部用户发布。

本页重点介绍应用开发,但许多 build 步骤和概念对大多数 build 类型来说都是通用的。

Android build 术语表

Gradle 和 Android Gradle 插件可帮助您完成 build 以下方面的配置:

build 类型

build 类型定义 Gradle 在构建和打包应用时使用的某些属性。通常针对开发生命周期的不同阶段进行配置。

例如,调试 build 类型会启用调试选项,并会使用调试密钥为应用签名;而发布 build 类型则可能会缩减应用大小、对应用进行混淆处理,并使用发布密钥为应用签名以进行分发。

如需构建应用,您必须至少定义一个 build 类型。Android Studio 默认会创建调试 build 类型和发布 build 类型。如要着手为应用自定义打包设置,不妨了解如何配置 build 类型

产品变种
产品变种代表您可以向用户发布的不同应用版本,如应用的免费版和付费版。您可以自定义产品变种以使用不同的代码和资源,同时共享并重用所有应用版本共用的部分。产品变种是可选的,您必须手动创建。如要开始创建应用的不同版本,请了解如何配置产品变种
build 变体
build 变体是 build 类型与产品变种的交叉产物,也是 Gradle 用来构建应用的配置。利用 build 变体,您可以在开发期间构建产品变种的调试版本,以及构建产品变种的已签名发布版本以供分发。虽然您无法直接配置 build 变体,但可以配置构成 build 变体的 build 类型和产品变种。创建额外的 build 类型或产品变种也会产生额外的 build 变体。如需了解如何创建和管理 build 变体,请参阅配置 build 变体概览。
清单条目
您可以在 build 变体配置中为清单文件的某些属性指定值。这些 build 值会覆盖清单文件中的现有值。如果您要为应用生成多个变体,让每一个变体都具有不同的应用名称、最低 SDK 版本或目标 SDK 版本,便可运用这一技巧。当存在多个清单时,清单合并工具会合并清单设置
依赖项
构建系统会管理来自本地文件系统以及来自远程代码库的项目依赖项。这样一来,您就不必手动搜索、下载依赖项的二进制文件包以及将它们复制到项目目录中。如需了解详情,请参阅添加 build 依赖项
签名
构建系统既允许您在 build 配置中指定签名设置,也可以在构建流程中自动为应用签名。构建系统通过已知凭据使用默认密钥和证书为调试版本签名,以避免在构建时提示输入密码。除非您为此 build 明确定义签名配置,否则,构建系统不会为发布版本签名。如果您没有发布密钥,可以按为应用签名中所述生成一个。通过大多数应用商店分发应用时都需要使用已签名的发布 build。
代码和资源缩减
构建系统允许您为每个 build 变体指定不同的 ProGuard 规则文件。在构建应用时,构建系统会应用一组适当的规则以使用其内置的缩减工具(如 R8)缩减您的代码和资源。 缩减代码和资源有助于缩减 APK 或 AAB 大小。
多 APK 支持
通过构建系统可以自动构建不同的 APK,并让每个 APK 只包含特定屏幕密度或应用二进制接口 (ABI) 所需的代码和资源。如需了解详情,请参阅构建多个 APK。不过,我们建议的方法是发布单个 AAB,因为它除了让您可以按屏幕密度和 ABI 进行拆分以外,还可以让您按语言进行拆分,同时无需将多个工件上传到 Google Play。2021 年 8 月之后提交的所有新应用都必须使用 AAB。

build 配置文件

如果您创建自定义 build 配置,就需要对一个或多个 build 配置文件(即 build.gradle 文件)做出更改。这些纯文本文件使用领域特定语言 (DSL) 以 Groovy 描述和操纵构建逻辑,其中 Groovy 是一种适用于 Java 虚拟机 (JVM)或 Kotlin 脚本(Kotlin 语言的一个变种)的动态语言。

您无需了解 Groovy 或 Kotlin 脚本即可开始配置 build,因为 Android Gradle 插件引入了您需要的大多数 DSL 元素。如需详细了解 Android Gradle 插件 DSL,请参阅 Groovy 的 DSL 参考文档。Kotlin 脚本还依赖于底层 Gradle Kotlin DSL

开始新项目时,Android Studio 会自动为您创建其中的部分文件(如图 1 所示),并为其填充合理的默认值。

图 1. Android 应用模块的默认项目结构。

有一些 Gradle build 配置文件是 Android 应用的标准项目结构的组成部分。您必须了解其中每个文件的范围和用途及其定义的基础 DSL 元素,才能着手配置 build。

Gradle 设置文件

settings.gradle 文件(对于 Groovy)或 settings.gradle.kts 文件(对于 Kotlin 脚本)位于项目的根目录下。此设置文件会定义项目级代码库设置,并告知 Gradle 在构建应用时应将哪些模块包含在内。多模块项目需要指定应包含在最终 build 中的每个模块。

对于大多数项目,该文件默认如下所示:

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 文件

顶层 build.gradle 文件(对于 Groovy)或 build.gradle.kts 文件(对于 Kotlin 脚本)位于项目的根目录下。它用于定义适用于项目中所有模块的依赖项。默认情况下,顶层 build 文件使用 plugins 代码块定义项目中所有模块共用的 Gradle 依赖项。此外,顶层 build 文件还包含用于清理 build 目录的代码。

以下代码示例说明了创建新项目后可在顶层 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.3.0' apply false
    id 'com.android.library' version '7.3.0' apply false
    id 'org.jetbrains.kotlin.android' version '1.7.20' 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.3.0" apply false
    id("com.android.library") version "7.3.0" apply false
    id("org.jetbrains.kotlin.android") version "1.7.20" 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.0"
    ...
}
...

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.0"
    ...
}
...

如需从同一项目中的某个模块访问这些属性,请在该模块的 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}")
    ...
}

注意:虽然 Gradle 可让您在模块级别定义项目全局属性,但您应避免这样做,因为这样会导致共享这些属性的模块相互结合。模块耦合使得以后将模块作为独立项目导出更加困难,并妨碍 Gradle 利用并行项目执行加快多模块 build。

模块级 build 文件

模块级 build.gradle 文件(对于 Groovy)或 build.gradle.kts(对于 Kotlin 脚本)位于每个 project/module/ 目录中,用于为其所在的特定模块配置 build 设置。您可以通过配置这些 build 设置提供自定义打包选项(如额外的 build 类型和产品变种),以及替换 main/ 应用清单或者顶层 build.gradlebuild.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.0'
    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.0")
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Gradle 属性文件

Gradle 还包含两个属性文件,它们位于项目的根目录下,可用于指定 Gradle 构建工具包本身的设置:

gradle.properties
您可以在其中配置项目全局 Gradle 设置,如 Gradle 守护程序的最大堆大小。如需了解详情,请参阅构建环境
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 文件同步

当您在项目中对 build 配置文件进行更改时,Android Studio 会要求您同步项目文件,以便它导入 build 配置更改并执行一些检查以确保您的配置不会造成 build 错误。

如要同步项目文件,请点击做出更改后显示的通知栏中的 Sync Now(如图 2 所示),或者点击菜单栏中的 Sync Project 图标 。如果 Android Studio 发现您的配置有任何错误(例如,您的源代码使用了只有在 compileSdkVersion 以上的 API 级别中才会提供的 API 功能),Messages 窗口就会说明相应的问题。

图 2. 在 Android Studio 中将项目与 build 配置文件同步。

源代码集

Android Studio 按逻辑关系将每个模块的源代码和资源分组为源代码集。当您创建新模块时,Android Studio 会在该模块内创建一个 main/ 源代码集。模块的 main/ 源代码集包含其所有 build 变体共用的代码和资源。

其他源代码集目录是可选的,在您配置新的 build 变体时,Android Studio 不会自动为您创建这些目录。不过,创建类似于 main/ 的源代码集有助于组织 Gradle 仅在构建特定应用版本时才应使用的文件和资源:

src/main/
此源代码集包含所有 build 变体共用的代码和资源。
src/buildType/
创建此源代码集可加入特定 build 类型专用的代码和资源。
src/productFlavor/
创建此源代码集可加入特定产品变种专用的代码和资源。

注意:如果配置 build 以组合多个产品变种,则可以为变种维度之间的每个产品变种组合创建源代码集目录:src/productFlavor1ProductFlavor2/

src/productFlavorBuildType/
创建此源代码集可加入特定 build 变体专用的代码和资源。

例如,如需生成应用的“fullDebug”版本,构建系统需要合并来自以下源代码集的代码、设置和资源:

  • src/fullDebug/(build 变体源代码集)
  • src/debug/(build 类型源代码集)
  • src/full/(产品变种源代码集)
  • src/main/(主源代码集)

注意:当您在 Android Studio 中使用 File > New 菜单选项新建文件或目录时,可以针对特定源代码集进行创建。可供您选择的源代码集取决于您的 build 配置,如果所需的目录尚不存在,Android Studio 会自动创建。

如果不同源代码集包含同一文件的不同版本,Gradle 将按以下优先顺序决定使用哪一个文件。左侧源代码集替换右侧源代码集的文件和设置:

build 变体 > build 类型 > 产品变种 > 主源代码集 > 库依赖项

这样一来,Gradle 便可使用专用于您试图构建的 build 变体的文件,同时重用与其他应用版本共用的 activity、应用逻辑和资源。

合并多个清单时,Gradle 会使用相同的优先顺序,这样每个 build 变体都能在最终清单中定义不同的组件或权限。如需详细了解如何创建自定义源代码集,请参阅创建源代码集

其他构建系统

Android 应用可以使用 Bazel 来构建,但这不是官方支持的方式。Android Studio 未正式支持 Bazel 项目。

如需更好地了解目前使用 Bazel 构建应用时存在的限制,请参阅已知问题