Gradle 构建概览

Android 应用通常使用 Gradle 编译系统构建而成。 系统。在深入了解如何配置 build 之前, 探索构建背后的概念,以便了解整个系统。

什么是 build?

构建系统将您的源代码转换为可执行应用。 构建通常涉及多个工具,以分析、编译、链接和打包您的 应用或库Gradle 使用基于任务的方法来组织和运行 这些命令

任务封装了可将其输入转换为 输出。插件定义任务及其配置。正在应用 添加到 build 的插件会注册其任务,并使用 输入和输出...例如,应用 Android Gradle 插件 (AGP) 会注册构建 APK 所需的所有任务,或 Android 库。借助 java-library 插件,您可以从 Java 源代码构建 jar 代码。类似的插件也可用于 Kotlin 和其他语言,但有其他插件 旨在扩展插件。例如,protobuf 插件旨在添加 对 AGP 或 java-library 等现有插件的 protobuf 支持。

Gradle 更倾向于使用惯例而不是配置,因此插件将提供良好的 默认值,但您可以通过 声明式域特定语言 (DSL)。DSL 所以你可以指定要构建的内容,而不是构建方式。这里的逻辑 插件管理“方式”。该配置是在 项目(和子项目)中的 build 文件

任务输入可以是文件和目录,以及编码为 Java 类型(整数、字符串或自定义类)。输出只能是目录 或文件,因为它们必须写入磁盘。将一个任务输出连接到另一个任务输出 将任务链接在一起,以便必须先运行另一个任务。

虽然 Gradle 支持在 build 中编写任意代码和任务声明 这可能会使工具更难理解您的 build 和 供您维护例如,您可以为插件内的代码编写测试 但不包含在构建文件中相反,您应该限制构建逻辑和任务, (由您自己或其他人定义)并声明 希望在构建文件中使用该逻辑

Gradle 构建运行时会发生什么?

Gradle 构建分三个阶段运行。这些阶段中的每一个执行不同的部分 您在构建文件中定义的代码

  • 初始化决定了包含哪些项目和子项目 并设置包含 build 文件和应用的 插件。此阶段侧重于设置文件,您可以在其中声明项目 以及从中提取插件和库的位置。
  • Configuration 会为每个项目注册任务,并执行构建 文件以应用用户的 build 规范。您有必要了解 配置代码将无法访问生成的数据或文件 。
  • Execution 用于执行实际的“构建”。输出 是任务的有向无环图 (DAG), 代表用户请求的所有必需构建步骤( 任务)。这个 表示任务之间的关系, 或基于其输入和输出。如果任务有一个输入, 是另一个任务的输出,因此必须在该任务之后运行。这个 阶段按照图表中定义的顺序运行过期任务;如果某个任务的 输入自上次执行以来没有更改,Gradle 将跳过它。

如需了解详情,请参阅 Gradle 构建生命周期

配置 DSL

Gradle 使用域特定语言 (DSL) 来配置 build。这种声明式方法侧重于指定数据,而不是 编写分步(命令式)指令。

DSL 致力于让所有人(无论是领域专家还是程序员)都能更轻松地 为项目做贡献,定义一种小语言来代表数据, 更自然的方式Gradle 插件可以扩展 DSL 以配置其 执行任务所需的资源

例如,配置 build 的 Android 部分可能如下所示:

Kotlin

android {
    namespace = "com.example.app"
    compileSdk = 34
    // ...

    defaultConfig {
        applicationId = "com.example.app"
        minSdk = 34
        // ...
    }
}

Groovy

android {
    namespace 'com.example.myapplication'
    compileSdk 34
    // ...

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdk 24
        // ...
    }
}

在后台,DSL 代码类似于以下内容:

fun Project.android(configure: ApplicationExtension.() -> Unit) {
    ...
}

interface ApplicationExtension {
    var compileSdk: Int
    var namespace: String?

    val defaultConfig: DefaultConfig

    fun defaultConfig(configure: DefaultConfig.() -> Unit) {
        ...
    }
}

DSL 中的每个块都由一个函数表示,该函数接受 lambda 来 配置该配置,以及一个同名属性来访问该配置。这样一来, 更像是一种数据规范。

外部依赖项

Maven 构建系统引入了 dependency 规范, 存储和管理系统库存储在 代码库(服务器或目录),其元数据包括 以及其对其他库的依赖关系您可以指定 要搜索的依赖项、要使用的依赖项的版本以及 并会在构建期间下载它们

Maven 制品通过群组名称(公司、开发者等)、工件标识 该工件的名称(库名称)和版本。这通常是 以 group:artifact:version 的形式表示。

此方法可显著改善构建管理。你经常听到 名为“Maven repositories” 封装和发布的软件工件这些代码库和元数据 在多个构建系统中重复使用(Gradle 可以发布到 这些代码库)。公共代码库允许所有人共享,并且 可将内部依赖项保存在内部。

您还可以将项目模块化为多个子项目 (在 Android Studio 中也称为“模块”),此类模块也可用作 依赖项每个子项目都会生成输出(例如 jar), 或顶级项目使用的资源。这可以缩短构建时间 通过隔离需要重建的部分, 责任。

我们将在添加 build 依赖项

build 变体

在创建 Android 应用时,您通常会希望构建多个 变体。变体包含不同的代码或使用不同的代码进行构建 由 build 类型和产品变种组成。

build 类型与声明的 build 选项不同。默认情况下,AGP 会设置“release” 和“debug”但您可以调整它们并添加更多类型(比如 预演测试或内部测试)。

调试版本不会缩小或混淆应用,从而加快其 按原样构建和保留所有符号它还会将该应用标记为 “debuggable”,使用通用调试密钥为其签名,并启用对 已安装的应用文件。这样,您就可以探索 在运行应用时将数据保存在文件和数据库中。

发布 build 会优化应用,使用您的发布密钥签署应用,以及 保护已安装的应用文件。

使用产品变种,您可以更改包含的源代码和依赖项 变体。例如,您可以创建“演示” 和“full”还是“免费”版本和“paid”口味。 您将通用源代码编写在“主源代码”中源代码集目录,以及 在以变种命名的源代码集中替换或添加源代码。

AGP 会为 build 类型和产品变种的每个组合创建变体。如果 则系统不会定义变种,而是以 build 类型命名变体。如果您 同时定义这两者,则变体的名称为 <flavor><Buildtype>。例如,对于 类型 releasedebug 以及变种 demofull,AGP 将创建 变体:

  • demoRelease
  • demoDebug
  • fullRelease
  • fullDebug

后续步骤

现在,您已经了解了构建概念,请查看Android build 结构