工具和库的相互依存关系

构建依赖项是成功构建项目所需的外部组件。build 可以依赖于库、插件、子项目、Android SDK、KotlinJava 编译器等工具、Android Studio 等开发环境,以及 Gradle 本身。

每个依赖项本身可能还需要其他依赖项。我们将这些依赖项称为“传递依赖项”,它们可能会迅速增加应用使用的总体依赖项数量。当您想要升级依赖项(无论是库、工具还是 Android SDK)时,该升级可能会级联,从而升级许多其他依赖项。

通常,这不会造成任何问题,因为许多库都遵循一种称为语义版本控制的方案。这些库会限制所做的更改类型,以便与其较低版本保持兼容。

语义版本控制遵循 major.minor.patch 格式。例如,在版本号 4.8.3 中,4 是 major 版本,8 是 minor 版本,3 是 patch 编号。当 major 部分发生变化时,库的 API 或行为可能会发生重大变化。这可能会影响您的 build 或应用行为。

minor(新功能)或 patch(bug 修复)部分发生变化时,库开发者会告知您该库仍然兼容,并且不会影响您的应用。

请务必留意此类更改,多种依赖项升级工具都可以为您提供帮助。

build 中的依赖项

Android build 包含以下各项之间的关系:

  • 源代码 - 您可以控制的代码和资源
  • 库依赖项 - 项目和子项目在构建时包含的外部库或模块
  • 工具 - 将源代码转换为应用或库的编译器、插件和 SDK
build 依赖项及其关系
图 1. 建立关系

源代码

源代码是您在应用或库中编写的 Kotlin 或 Java 代码。(如需详细了解如何使用 C++,请参阅 Android NDK。)

源代码依赖于库(包括 Kotlin 和 Java 运行时库)及 Android SDK,并需要对应的 Kotlin 或 Java 编译器。

某些源代码包含需要额外处理的注解。例如,如果您编写 Jetpack Compose 代码,则需要添加 Compose Kotlin 编译器插件需要处理的注解,例如 @Composable。其他注解可以由 Kotlin 符号处理器 (KSP) 或单独的注解处理工具处理。

库依赖项

这些库包含作为应用的一部分提取的字节码。这可以是 Java JAR、Android 库 (AAR) 或 build 中的子项目。许多库都遵循语义版本控制,这有助于您了解升级后这些库是否保持兼容性。

库可能会依赖于其他库以进行重复使用,这称为传递依赖项。这样可以减少您必须明确管理的依赖项;您指定要直接使用的依赖项,Gradle 会将它们与传递依赖项一起拉取。请注意,在升级直接依赖项时,它们可能会升级这些传递依赖项。

有时,库在运行时 (minSdk) 或编译时 (compileSdk) 可能需要最低版本的 Android SDK。当库使用 Android SDK 或其提供的 JDK API 中包含的函数时,就需要这样做。应用的有效 minSdk 是指应用及其所有直接和传递库依赖项所请求的最高 minSdk

使用某些库可能需要使用特定的 Gradle 插件。这些辅助插件通常会安装 Kotlin 符号处理器或其他注解处理器,这些处理器会生成代码或修改源代码的编译,以支持您使用库功能。例如,Jetpack Room 包含注解和 KSP,可将注解转换为生成的代码,以检索和修改数据库中的数据。Jetpack Compose 要求 Compose 编译器插件修改带注解的函数,以管理重新运行该函数的方式和时间。

工具

Gradle

Gradle 是一种构建工具,用于读取 build 文件并生成应用或库,还会公开 API 以供插件扩展其功能。Gradle 在一个或多个 Java 虚拟机上运行多个进程,其 Java 插件会调用 JDK 中的 Java 工具。

Gradle 插件

Gradle 插件通过定义新任务和配置来扩展 Gradle。将插件应用于 build 可启用特定 build 功能,这些功能会在 build 脚本中配置为数据。对于 Android build,最重要的 Gradle 插件是 Android Gradle 插件 (AGP)。

编译器

Kotlin 或 Java 编译器会将您的源代码转换为可执行字节码。Kotlin 编译器公开了一个插件 API,可让外部分析和代码生成直接在编译器内运行,从而访问解析的代码结构。

编译器插件

在 Kotlin 编译器分析代码时,编译器插件会在 Kotlin 编译器执行分析和代码生成操作,并且在您将其 Gradle 插件应用于 build 时进行安装。

Android SDK

Android SDK 包含特定 Android 版本的 Android 平台和 Java API,以及相应的工具。这些工具可帮助您管理 SDK、构建应用,以及与 Android 设备通信并模拟 Android 设备。

每个版本的 Android SDK 都提供您的源代码可以访问的特定 Java API,并提供脱糖支持,以便在较低版本的 Android 上使用这些 API。

JDK

Java 开发套件,包含用于编译 Java 源代码和运行 Java 应用的 Java 库和可执行文件。在 Android build 中,有几个 JDK 会发挥作用。如需了解详情,请参阅 Android build 中的 Java 版本

Gradle 作用域

Gradle 将库依赖项分组为不同的范围(在 Gradle API 中称为“配置”),从而允许您指定要在 build 的不同部分中使用的库依赖项集。例如,您可能不希望在已发布的应用或库中添加 JUnit 等测试库,但在构建和执行单元测试时需要这些库。您还可以使用作用域添加符号或注解处理程序来分析代码。

例如,AGP 定义了 implementationapi 作用域,您可以通过这些作用域指定是否应将依赖项公开给子项目的用户。如需了解 Android build 中使用的这些作用域及其他作用域的说明,请参阅配置依赖项

在 build 文件的 dependencies 代码块中,以 group:artifact:version 字符串的形式添加库依赖项:

Kotlin

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation("com.example:library1:1.2.3")
    api("com.example:library2:1.1.1")
}

Groovy

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation 'com.example:library1:1.2.3'
    api 'com.example:library2:1.1.1'
}

或在版本目录中:

# Version catalog - gradle/libs.versions.toml
[versions]
exampleLib = "1.2.3"
examplePlugin = "2.3.4"

[libraries]
example-library = { group = "com.example", name = "library", version.ref = "exampleLib" }

[plugins]
example-plugin = { id = "com.example.plugin", version.ref = "examplePlugin" }

并在 build 文件中指定生成的变量:

Kotlin

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation(libs.example.library)
}

Groovy

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation libs.example.library
}