Skip to content

解决 Gradle 仓库配置错误:'Build was configured to prefer settings repositories over project repositories'

问题描述

在使用 Gradle 构建 Android 项目时,当你尝试在 build.gradle 文件中添加 JitPack 或其他自定义 Maven 仓库时,可能会遇到以下错误:

text
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 文件中包含以下配置:

groovy
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

repositoriesMode 设置为 FAIL_ON_PROJECT_REPOS 时,Gradle 会阻止在项目级 build.gradle 文件中声明仓库,强制要求所有仓库都在 settings.gradle 中统一管理。

解决方案

根据你的项目需求和偏好,有以下两种解决方案:

方案一:保留中央仓库声明(推荐)

这是 Gradle 推荐的现代做法,将所有仓库统一在 settings.gradle 文件中管理。

  1. 移除 build.gradle 文件中的 allprojects 代码块
  2. 修改 settings.gradle 文件,添加所需的仓库:
groovy
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' } // 添加 JitPack 仓库
        // 其他自定义仓库...
    }
}
  1. 同步项目(点击 Android Studio 右上角的 "Sync Now")

TIP

对于需要认证的私有仓库,可以这样配置:

groovy
maven {
    name = "GitHubPackages"
    url = uri("https://maven.pkg.github.com/OWNER/REPOSITORY")
    credentials {
        username = project.findProperty("githubUsername") ?: ""
        password = project.findProperty("githubToken") ?: ""
    }
}

方案二:禁用中央仓库声明

如果你希望继续使用传统的项目级仓库声明方式:

  1. 删除 settings.gradle 文件中的整个 dependencyResolutionManagement 代码块
  2. 保留 build.gradle 文件中的 allprojects 代码块:
groovy
allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}
  1. 同步项目

WARNING

虽然这种方法可以解决问题,但不建议长期使用,因为中央仓库声明是 Gradle 的未来发展方向,能提供更好的性能和一致性。

方案三:修改仓库模式(折中方案)

如果你既想保留中央仓库声明,又希望允许项目级仓库:

groovy
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

这种模式下,Gradle 会优先使用设置在 settings.gradle 中的仓库,但同时允许项目级 build.gradle 中声明的仓库。

最佳实践

  1. 统一管理:尽量将所有仓库声明集中在 settings.gradle 文件中
  2. 版本兼容:确保使用的 Gradle 插件版本与 Gradle 版本兼容
  3. 仓库顺序:按照依赖来源频率排序仓库,将最常用的仓库放在前面以提高构建性能
  4. 安全存储:对于需要认证的仓库,将凭据存储在 gradle.properties 或环境中,不要硬编码在构建文件中

完整配置示例

以下是一个完整的 settings.gradle 配置示例:

groovy
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 的中心化仓库声明机制是为了提高构建的可预测性和性能。虽然初期可能需要调整原有的配置习惯,但遵循这一新模式能够带来更好的长期维护体验。根据你的项目需求,选择最适合的解决方案,并确保团队中的所有成员遵循相同的配置规范。