settings.gradle 是 Gradle 的根配置文件,用于定义多模块项目的结构:哪些模块参与构建、哪些插件可用以及如何解析依赖关系。build.gradle 描述如何构建每个模块,而 settings.gradle 描述项目由哪些模块组成。根据 Gradle Documentation, 2025,正确配置 settings.gradle 可通过优化模块解析将多模块项目的配置时间减少 25%。该文件在 Initialization 阶段执行——这是 Gradle 构建生命周期的第一阶段。
要点
settings.gradle(或用于 Kotlin DSL 的 settings.gradle.kts)是 Gradle 在 Initialization 阶段执行的文件。它定义项目的层次结构、引入模块、配置插件和依赖的仓库。没有 settings.gradle,Gradle 不知道要构建哪些模块以及哪些插件可用。在单模块项目中,可以没有 settings.gradle——Gradle 使用默认值,但对于多模块项目是必须的。
settings.gradle 文件位于项目根目录,紧挨着根 build.gradle。项目根目录的典型结构:settings.gradle.kts、build.gradle.kts、gradle.properties、local.properties、gradle/wrapper/。settings.gradle 在 build.gradle 之前执行——在 Initialization 阶段,Gradle 构建项目树(Gradle API 中的 Project)。Initialization 完成后,开始 Configuration——执行每个模块的 build.gradle。
历史上,settings.gradle 出现在 Gradle 0.7(2010 年),最初只包含 include 指令。随着 Gradle 的发展,pluginManagement(Gradle 6.8)、dependencyResolutionManagement(Gradle 7.0)和 versionCatalogs(Gradle 7.4)被添加到 settings.gradle。现代的 settings.gradle 是一个强大的配置文件,它为整个项目集中管理插件、仓库和版本。Google 从 AGP 8.0 开始将这些功能固化到 Android Gradle Plugin 中。
settings.gradle 管理项目的结构和全局设置(插件、仓库)。build.gradle 管理构建(依赖、Android 配置、任务)。settings.gradle 首先执行,并可访问 Settings API。build.gradle 稍后执行,并可访问 Project API。任何模块配置(android 块、dependencies)都不能出现在 settings.gradle 中——这是错误的。
include 指令是 settings.gradle 中的主要指令。它告诉 Gradle 哪些模块应参与构建。include 的参数是模块路径:include(":app")——引入根目录中的模块,include(":core:network")——位于 core/network/ 子目录中的模块。开头的冒号表示路径相对于项目根目录。执行 include 后,Gradle 会自动在指定目录中找到 build.gradle 并将模块添加到项目树中。
每个 include 在 Gradle API 中创建一个 Project,其名称等于 include 字符串。项目名称用于其他模块的 build.gradle 中的 implementation(project(":module"))。如果模块没有通过 include 引入,从其他模块引用它会导致 "Project not found" 错误。Android Studio IDE 也使用 settings.gradle 在 Project 面板中显示模块——没有 include 的模块在文件树中不可见。
include 通过 includeBuild("../library-project") 支持 included builds 和 composite builds。这允许将整个 Gradle 项目作为外部模块引入。Included builds 对于并行开发库和应用程序非常有用:库中的更改无需发布到 maven 仓库即可立即在应用程序中看到。在生产构建中,includeBuild 被普通的 maven 依赖替换。
// settings.gradle.kts — 典型结构
rootProject.name = "MyApp"
// 应用程序模块
include(":app")
include(":core:network")
include(":core:database")
include(":core:ui")
include(":feature:home")
include(":feature:profile")
include(":feature:settings")
// 引入外部库 (composite build)
includeBuild("../my-analytics-lib") {
dependencySubstitution {
substitute(module("com.example:analytics"))
.using(project(":analytics"))
}
}
pluginManagement——settings.gradle 中的一个块,用于确定从何处加载 Gradle 插件。出现于 Gradle 6.8,用于在应用插件之前对其进行集中管理。pluginManagement 内部包含:repositories(搜索插件的仓库列表)、resolutionStrategy(版本解析规则)和 plugins(显式指定插件版本)。如果未设置 pluginManagement,Gradle 会使用 build.gradle 中的仓库——但插件只有在声明之后才会被搜索,如果未找到插件会导致错误。
在 Android 项目中,如果使用版本目录或 Convention Plugins,则必须使用 pluginManagement。如果没有 pluginManagement,Gradle 在 build.gradle.kts 中应用时将无法找到 com.android.application 插件。典型配置:repositories 包含 google()(Android 插件)、mavenCentral()(第三方插件)和 gradlePluginPortal()(官方 Gradle 插件)。
pluginManagement 还支持 plugins——声明带版本的插件,然后在 build.gradle 中应用时无需指定版本。这样可以集中管理插件版本:如果 10 个模块应用 kotlin-android,版本只需在 pluginManagement 中指定一次。重要:pluginManagement.plugins 只是声明。插件本身通过 plugins { id("org.jetbrains.kotlin.android") } 在 build.gradle 中应用。
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
maven { url = "https://jitpack.io" }
}
// 插件版本 — 集中管理
plugins {
id("com.android.application") version "8.7.0"
id("com.android.library") version "8.7.0"
id("org.jetbrains.kotlin.android") version "2.0.21"
id("com.google.devtools.ksp") version "2.0.21-1.0.25"
}
resolutionStrategy {
// 所有模块的强制插件版本
eachPlugin {
if (requested.id.id == "com.google.gms.google-services") {
useVersion("4.4.2")
}
}
}
}
plugins {
// 应用插件 — apply false(不应用于根目录)
id("com.android.application") apply false
id("org.jetbrains.kotlin.android") apply false
}
dependencyResolutionManagement——settings.gradle 中的一个块,用于集中管理所有模块的仓库。出现于 Gradle 7.0,作为在每个 build.gradle 中声明 repositories 的替代方案。块内设置 repositoriesMode(模式:PREFER_PROJECT、PREFER_SETTINGS 或 FAIL_ON_PROJECT_REPOS)和 repositories(仓库列表)。如果 repositoriesMode = PREFER_SETTINGS,模块的 repositories 将被忽略——仅使用集中列表。
repositoriesMode 可以取三个值。PREFER_SETTINGS——build.gradle 中的仓库被忽略,仅使用 settings.gradle 中的仓库。PREFER_PROJECT——build.gradle 的仓库优先于 settings.gradle。FAIL_ON_PROJECT_REPOS——如果模块声明自己的仓库,Gradle 会报错。对于新项目,建议使用 PREFER_SETTINGS——这能确保所有模块使用相同的仓库,并消除重复。
repositoriesMode = FAIL_ON_PROJECT_REPOS 在团队中特别有用:如果开发者只向一个模块添加仓库而其他模块看不到,就会出现 "works on my machine" 的情况。FAIL_ON_PROJECT_REPOS 强制所有仓库集中声明在 settings.gradle 中,从而防止此类情况。Google 建议从 AGP 8.0 开始的所有 Android 项目使用 FAIL_ON_PROJECT_REPOS。
dependencyResolutionManagement {
// FAIL_ON_PROJECT_REPOS — 所有仓库仅在此处
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = "https://jitpack.io" }
// 私有 maven 仓库
maven {
url = "https://maven.pkg.github.com/company/internal-lib"
credentials {
username = providers.gradleProperty("gpr.user")
.getOrNull() ?: System.getenv("GPR_USER") ?: ""
password = providers.gradleProperty("gpr.key")
.getOrNull() ?: System.getenv("GPR_KEY") ?: ""
}
}
}
}
// 模块的 build.gradle 中不再需要 repositories!
// 所有仓库集中在 settings.gradle 中
版本目录是通过 TOML 文件集中管理依赖版本的方式。从 Gradle 7.4 开始,版本目录是所有 Android 项目的推荐机制。gradle/libs.versions.toml 文件包含三个部分:[versions](版本)、[libraries](依赖)、[plugins](插件)。在 settings.gradle 中,版本目录通过 @Suppress("UnstableApiUsage") 和 enableFeaturePreview("VERSION_CATALOGS")(在旧版 Gradle 中)引入。
引入版本目录后,在模块的 build.gradle 中,依赖通过 libs 指定:implementation(libs.retrofit)。IDE 为 libs 提供自动补全。目录自动生成 type-safe accessors:libs.retrofit、libs.kotlin.coroutines、libs.bundles.compose。Bundles 是可以一行引入的依赖组。版本目录还支持继承——可以引入多个 TOML 文件。
版本目录的优势:版本统一管理(无需在所有 build.gradle 中查找);type-safe 访问(libs 名称错误在编译阶段检测到,而非运行时);自动更新(Dependabot 和 Renovate 支持 TOML);与 Convention Plugins 兼容。Google Firebase 和 AndroidX 分发自己的 TOML 目录。对于迁移到版本目录,存在可以自动将 build.gradle 中的版本转移到 TOML 的插件。
# gradle/libs.versions.toml
[versions]
agp = "8.7.0"
kotlin = "2.0.21"
composeBom = "2024.12.01"
retrofit = "2.11.0"
coroutines = "1.9.0"
[libraries]
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
retrofit-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
compose-ui = { module = "androidx.compose.ui:ui" }
[bundles]
compose = ["compose-ui", "compose-material3"]
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
includeBuild 是用于创建 composite build 的指令:将外部 Gradle 项目作为当前构建的一部分引入。与 include(引入模块)不同,includeBuild 引入整个项目及其自己的 settings.gradle、模块和插件。Composite builds 用于:与应用程序并行开发库(分析、网络);从单独仓库引入 Convention Plugins;集成 build-logic 模块。
孵化功能(Incubating Features)——通过 enableFeaturePreview("FEATURE_NAME") 启用的实验性 Gradle 选项。在 AGP 8.7+ 中可用:TYPESAFE_PROJECT_ACCESSORS(在多模块项目中对项目的 type-safe 访问:不再使用 project(":core:network"),可以写 projects.core.network)、STABLE_CONFIGURATION_CACHE(稳定的配置缓存)、ARTIFACT_TRANSFORM_FOR_INTERNAL_TEST(工件转换)。孵化功能可以在生产环境中启用,但 API 可能在将来版本中发生变化。
Gradle Enterprise 和 Build Scan 也通过 settings.gradle 配置:plugins { id("com.gradle.enterprise") } 以及 gradleEnterprise 块。Build Scan 是一种云服务,显示每次构建的详细信息:每个任务的执行时间、缓存、错误。启用 Build Scan 有助于诊断构建速度问题。对于开源项目,Build Scan 是免费的。
// 孵化功能
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
enableFeaturePreview("STABLE_CONFIGURATION_CACHE")
// Gradle Enterprise / Build Scan
plugins {
id("com.gradle.enterprise") version "3.18"
}
gradleEnterprise {
buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service"
termsOfServiceAgree = "yes"
publishAlwaysIf(true)
}
}
// 在 build.gradle 中使用 type-safe project accessors
// 替代:implementation(project(":core:network"))
// 可以:implementation(projects.core.network)
常见问题
对于单模块项目,Gradle 可以使用默认值。但对于 AGP 8+,建议始终拥有 settings.gradle,因为 pluginManagement 和 dependencyResolutionManagement 是版本目录和 Convention Plugins 正常工作的必要条件。
include 从当前项目引入模块(一个模块树)。includeBuild 将外部 Gradle 项目作为 composite build 引入。includeBuild 便于在同一个仓库中开发库或引入 Convention Plugins。
在 settings.gradle 中添加 include(":模块名"),并创建包含 build.gradle 的目录。Android Studio 在通过 File → New → New Module 创建模块时会自动执行此操作。添加后,执行 Sync Project with Gradle Files。
不可以,pluginManagement 是专门用于 settings.gradle 的块。它在 Initialization 阶段执行,在任何 build.gradle 文件之前。在 build.gradle 中,插件仅被应用,而非管理。
每个模块将不得不在自己的 build.gradle 中声明 repositories。这会导致代码重复和失去同步的风险(一个模块添加了仓库,另一个没有)。dependencyResolutionManagement 集中管理仓库,防止 "works on my machine" 类型的错误。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。