解决 Gradle 仓库配置错误:'Build was configured to prefer settings repositories over project repositories'
问题描述
在使用 Gradle 构建 Android 项目时,当你尝试在 build.gradle
文件中添加 JitPack 或其他自定义 Maven 仓库时,可能会遇到以下错误:
Caused by: org.gradle.api.InvalidUserCodeException: Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by build file 'build.gradle'
这个错误通常发生在 Gradle 6.8 及以上版本中,因为 Gradle 引入了新的依赖管理机制,要求开发者使用中心化的仓库声明方式。
问题原因
从 Gradle 6.8 开始,引入了中央仓库声明(Centralized Repository Declaration)功能。新创建的项目默认会在 settings.gradle
文件中包含以下配置:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
当 repositoriesMode
设置为 FAIL_ON_PROJECT_REPOS
时,Gradle 会阻止在项目级 build.gradle
文件中声明仓库,强制要求所有仓库都在 settings.gradle
中统一管理。
解决方案
根据你的项目需求和偏好,有以下两种解决方案:
方案一:保留中央仓库声明(推荐)
这是 Gradle 推荐的现代做法,将所有仓库统一在 settings.gradle
文件中管理。
- 移除
build.gradle
文件中的allprojects
代码块 - 修改
settings.gradle
文件,添加所需的仓库:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' } // 添加 JitPack 仓库
// 其他自定义仓库...
}
}
- 同步项目(点击 Android Studio 右上角的 "Sync Now")
TIP
对于需要认证的私有仓库,可以这样配置:
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/OWNER/REPOSITORY")
credentials {
username = project.findProperty("githubUsername") ?: ""
password = project.findProperty("githubToken") ?: ""
}
}
方案二:禁用中央仓库声明
如果你希望继续使用传统的项目级仓库声明方式:
- 删除
settings.gradle
文件中的整个dependencyResolutionManagement
代码块 - 保留
build.gradle
文件中的allprojects
代码块:
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
- 同步项目
WARNING
虽然这种方法可以解决问题,但不建议长期使用,因为中央仓库声明是 Gradle 的未来发展方向,能提供更好的性能和一致性。
方案三:修改仓库模式(折中方案)
如果你既想保留中央仓库声明,又希望允许项目级仓库:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
这种模式下,Gradle 会优先使用设置在 settings.gradle
中的仓库,但同时允许项目级 build.gradle
中声明的仓库。
最佳实践
- 统一管理:尽量将所有仓库声明集中在
settings.gradle
文件中 - 版本兼容:确保使用的 Gradle 插件版本与 Gradle 版本兼容
- 仓库顺序:按照依赖来源频率排序仓库,将最常用的仓库放在前面以提高构建性能
- 安全存储:对于需要认证的仓库,将凭据存储在
gradle.properties
或环境中,不要硬编码在构建文件中
完整配置示例
以下是一个完整的 settings.gradle
配置示例:
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
// 其他自定义仓库...
}
}
rootProject.name = "YourAppName"
include ':app'
总结
Gradle 的中心化仓库声明机制是为了提高构建的可预测性和性能。虽然初期可能需要调整原有的配置习惯,但遵循这一新模式能够带来更好的长期维护体验。根据你的项目需求,选择最适合的解决方案,并确保团队中的所有成员遵循相同的配置规范。