返回

Gradle报错:解决 Cannot resolve dependency 无仓库定义

Android

搞定 Gradle 报错:Cannot resolve external dependency ... because no repositories are defined

写代码嘛,遇到点糟心事儿很正常。这不,碰上个 Gradle 构建错误,提示 Cannot resolve external dependency com.android.tools:desugar_jdk_libs:1.0.9 because no repositories are defined,是不是很头疼?特别是像这位朋友一样,升级个 Android Studio 版本,或者啥也没动,突然项目就跑不起来了,一堆库都报找不到。

看这报错信息:

Could not resolve all files for configuration ':app:coreLibraryDesugaring'.
Cannot resolve external dependency com.android.tools:desugar_jdk_libs:1.0.9 because no repositories are defined.
Required by:
    project :app

... (后面还有一大串类似的错误,涉及 databinding, appcompat, material 等)

别慌,这问题通常不复杂,咱们一步步把它摆平。

一、问题出在哪儿?为啥找不到库?

错误信息说得很直白:“because no repositories are defined”。

啥意思?就是你的项目(具体到这个例子,是 :app 这个模块)在编译的时候,需要去下载一些外部的依赖库,比如 desugar_jdk_libsappcompatdatabinding 这些。但是呢,它不知道该去哪里 下载!你没给它指定“仓库地址”。

这就好比你要去超市买东西,结果连哪个超市、地址在哪儿都不知道,那肯定买不到呀。

你可能会说:“不对啊,我项目根目录的 build.gradle 文件里明明写了 repositories!”

// Top-level build file (annexandroid/build.gradle)
buildscript {
    repositories {
        google()
        mavenCentral()
        jcenter() // 注意:JCenter 已停止服务,新项目不建议使用
        maven { url "https://jitpack.io" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.1.2'
        // ... 其他构建脚本依赖
    }
}

// ... (可能还有 allprojects 或 subprojects 块)

注意看!这个 repositories 是在 buildscript 代码块里面的。这里的仓库地址,是 Gradle 构建系统本身 用来下载构建插件(比如 com.android.tools.build:gradle 这个 Android Gradle 插件)的地方。

不负责 告诉你的 App 模块或 Library 模块 去哪里下载它们自己代码里 implementationapicoreLibraryDesugaring 声明的那些依赖库。

看看出问题的 :app 模块的 build.gradle 文件 ( app/build.gradle ):

// app/build.gradle
apply plugin: 'com.android.application'
// ... 其他插件

android {
    // ... 配置
    compileOptions {
        coreLibraryDesugaringEnabled true // 启用了核心库 desugaring
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    // ... 其他配置
}

dependencies {
    // ... 一堆依赖
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.0.0'
    // ... 等等

    // 这里声明了 desugar 库依赖
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'

    // !!! 关键问题:这个文件里,或者能影响这个文件的全局配置里,
    // !!! 没有指定下载这些依赖的 repositories
}

看到了吧?在 app/build.gradle 文件里,以及提供的 axnetwork-lib/build.gradle 文件里,都没有明确告诉 Gradle 去哪里找 appcompatmaterial,当然也包括 desugar_jdk_libs。所以,Gradle 两眼一抹黑,直接报错。

二、咋解决?指条明路给 Gradle

既然知道了问题是没指定仓库地址,那解决方案就是告诉 Gradle 去哪儿找。现在 Gradle 项目推荐的方式越来越统一,但也得看你的项目结构。主要有下面几种方法:

方案一:在项目根目录 settings.gradle (或 settings.gradle.kts) 中集中管理(推荐)

这是现代 Gradle 项目最推荐 的做法。好处是集中管理,所有模块默认都用这些仓库,干净利落。

  1. 原理和作用:
    settings.gradle 文件在 Gradle 构建生命周期的早期执行,dependencyResolutionManagement 块专门用于配置所有子项目的依赖解析策略,包括去哪些仓库找依赖。在这里配置后,所有模块都会自动应用这些设置。

  2. 操作步骤:
    打开你项目最外层的 settings.gradle 文件(如果用 Kotlin DSL 就是 settings.gradle.kts),添加或修改 dependencyResolutionManagement 部分。

    // settings.gradle
    
    pluginManagement {
        repositories {
            google()
            mavenCentral()
            gradlePluginPortal() // 下载 Gradle 插件的仓库
        }
    }
    
    // 核心在这里!
    dependencyResolutionManagement {
        // 配置哪些仓库对所有项目生效
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) // 推荐:禁止在子项目 build.gradle 里单独配仓库,保持统一
        repositories {
            google()       // 必须!Android 相关库,包括 desugar_jdk_libs 都在这
            mavenCentral() // 大部分 Java 开源库在这里
            // 如果你的项目依赖 jitpack.io 或其他私有仓库,也在这里加上
            maven { url "https://jitpack.io" }
            // 例如,私有 Maven 仓库
            // maven {
            //     url 'https://your.private.repo.url'
            //     credentials {
            //         username 'yourUsername'
            //         password 'yourPassword'
            //     }
            // }
        }
    }
    
    rootProject.name = "AnnexAndroid" // 你的项目名
    include ':app'
    include ':axnetwork-library'
    include ':draggablechip-library' // 确保所有模块都被 include
    

    解释:

    • google(): Google 的 Maven 仓库,包含所有 AndroidX 库、Material Components、desugar_jdk_libs 等。必须添加!
    • mavenCentral(): 最常用的公共 Java 仓库。
    • jitpack.io: 如果你用了像 groupie 这种托管在 JitPack 上的库(虽然你项目里似乎是通过 com.xwray groupId 直接从 Maven Central 获取的,但你的根 build.gradle 里有 JitPack,所以这里也加上以防万一),就需要这个。
    • repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS): 这是一个好习惯。它会强制要求所有仓库都在 settings.gradle 里定义,如果哪个模块的 build.gradle 里偷偷写了 repositories { ... },构建就会失败。这能避免混乱。
  3. 安全建议:

    • 优先使用官方仓库: google()mavenCentral() 是最常用且相对受信赖的。
    • 使用 HTTPS: 确保所有仓库地址都用 https://,避免中间人攻击。上面例子里默认都是 HTTPS。
    • 谨慎添加第三方仓库: 对于 jitpack.io 或私有仓库,确认其来源可靠。
    • JCenter 已弃用: 你的根 build.gradlebuildscript 里还有 jcenter()。虽然它可能还能工作一段时间,但官方已宣布停止维护,存在安全风险。尽快移除对 JCenter 的依赖,寻找替代库或确认库已迁移到 mavenCentral()google()

方案二:在项目根目录 build.gradle 中为所有模块配置(旧方式,兼容用)

如果你的项目比较老,或者由于某些原因不能用 settings.gradle 管理,可以在项目根目录的 build.gradle 文件中使用 allprojectssubprojects 块来配置。

  1. 原理和作用:
    allprojects 块中的配置会应用到根项目和所有子项目。subprojects 只应用到子项目。在这里添加 repositories,效果类似于在每个子项目的 build.gradle 文件里都添加一遍。

  2. 操作步骤:
    打开项目根目录的 build.gradle 文件 ( annexandroid/build.gradle ),在 buildscript 之外添加 allprojects 块(如果已有,就往里面加 repositories)。

    // Top-level build file (annexandroid/build.gradle)
    
    buildscript {
        // ... (保持不变)
    }
    
    // 为所有项目 (根项目 + 所有子模块) 配置仓库
    allprojects {
        repositories {
            google()       // 必须!
            mavenCentral() // 常用库
            // 根据需要添加其他仓库
            maven { url "https://jitpack.io" }
            // jcenter() // 同样,不推荐继续使用
        }
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    
  3. 安全建议: 同方案一。

  4. 注意:
    这种方式没有 settings.gradlerepositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 那么强的约束力,子项目仍然可能覆盖或添加自己的仓库,容易造成管理混乱。

方案三:在每个需要依赖的模块 build.gradle 文件中单独添加(不推荐,除非特殊情况)

最不推荐的做法,但如果你只想给某个特定模块(比如 :app)指定仓库,或者你的项目结构非常特殊,也可以这样做。

  1. 原理和作用:
    直接在模块的 build.gradle 文件(比如 app/build.gradle)的顶层(android { ... }dependencies { ... } 平级)添加 repositories 块。这样 Gradle 就知道去哪里找这个模块声明的依赖了。

  2. 操作步骤:
    打开 app/build.gradle 文件,添加 repositories 块。

    // app/build.gradle
    apply plugin: 'com.android.application'
    // ... 其他插件
    
    // 在这里添加仓库配置
    repositories {
        google()
        mavenCentral()
        // 根据 app 模块的特定依赖,可能还需要其他仓库
        maven { url "https://jitpack.io" } // 如果 app 模块直接依赖 JitPack 上的库
    }
    
    android {
        // ... 配置
    }
    
    dependencies {
        // ... 依赖列表
        coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
        // ...
    }
    

    同样地,你可能也需要在 axnetwork-lib/build.gradle 文件里做类似操作,因为它也有外部依赖。

  3. 安全建议: 同方案一。

  4. 缺点:

    • 重复配置: 如果多个模块都需要相同的仓库,你就得在每个模块里都写一遍,容易出错,难以维护。
    • 管理混乱: 各个模块仓库不统一,可能导致版本冲突或奇怪的解析问题。

三、其他辅助检查

应用了上述方案后,通常问题就解决了。如果还不行,可以尝试以下步骤:

  1. 检查网络和代理设置:

    • 网络连接: 确保你的电脑能正常访问 google.comrepo1.maven.org 这些地址。
    • 代理: 如果你处在需要代理的网络环境(比如公司内网),需要正确配置 Gradle 的代理。在项目根目录创建或修改 gradle.properties 文件,添加类似如下配置(根据你的实际代理服务器地址和端口修改):
      systemProp.http.proxyHost=your.proxy.host
      systemProp.http.proxyPort=your_proxy_port
      systemProp.https.proxyHost=your.proxy.host
      systemProp.https.proxyPort=your_proxy_port
      # 如果代理需要用户名密码认证
      # systemProp.http.proxyUser=your_username
      # systemProp.http.proxyPassword=your_password
      # systemProp.https.proxyUser=your_username
      # systemProp.https.proxyPassword=your_password
      
      修改后,最好重启 Android Studio 或执行一次 Clean Project
  2. 清理 Gradle 缓存并刷新依赖:
    有时候 Gradle 的缓存可能出了问题。

    • Android Studio 菜单: 选择 File > Invalidate Caches / Restart... > Invalidate and Restart。这会清理 AS 的缓存和索引。
    • 手动删除缓存: 关闭 Android Studio,然后手动删除用户主目录下的 .gradle/caches 文件夹。Windows 一般在 C:\Users\YourUsername\.gradle\caches,macOS/Linux 在 ~/.gradle/caches注意: 这会删除所有项目的缓存,下次构建会重新下载所有依赖,可能比较慢。
    • 命令行刷新: 在项目根目录的终端执行命令:
      • ./gradlew clean build --refresh-dependencies (macOS/Linux)
      • gradlew.bat clean build --refresh-dependencies (Windows)
        --refresh-dependencies 会强制 Gradle 重新检查依赖,而不是使用缓存的版本信息。

通常情况下,正确地在 settings.gradle(首选)或项目根 build.gradle 中添加 google()mavenCentral() 仓库就能解决 Cannot resolve external dependency ... because no repositories are defined 这类问题。毕竟,得告诉 Gradle 去哪儿找东西,它才能干活嘛!