Gradle下载慢?换源、离线包与缓存优化实战指南
2026/9/17 4:28:48 网站建设 项目流程

做 Android 或者 Java 后端的朋友,几乎没人没被 Gradle Download 卡过。新项目一打开,Android Studio 右下角转圈,日志停在 Downloading https://services.gradle.org/distributions/... 半天不动;或者依赖解析卡在某个仓库上,等了十分钟最后抛一个 SocketTimeoutException;运气好一点的,下载到 99% 又开始重来。这些场景我全经历过,而且不止一次,所以看到"解决 Gradle Download 缓慢的百种方法"这种标题,我是真的会心一笑——标题看着夸张,但被卡到怀疑人生的开发者,确实愿意把网上的偏方都试一遍。这篇内容就围绕我这些年实际用过的方案做个系统梳理,核心思路其实就三件事:换源、离线、缓存。先定位你卡在哪个环节,再对症下药,才能把一次构建从"看运气"变成"可预期"。

1. 先搞清楚你的 Gradle 到底慢在哪里

1.1 Gradle 发行版下载 vs 依赖下载,两件事别混为一谈

很多人一上来就搜"gradle 国内镜像",然后照着教程把 distributionUrl 改了,结果换完还是卡,就一脸懵。原因很简单:Gradle 慢有两种完全不同的场景,解决方案不通用。

第一种是 Gradle 发行版下载。现在的项目基本都带 Wrapper,就是你仓库根目录下 gradle/wrapper/gradle-wrapper.properties 这个文件里配置的 distributionUrl。默认指向 services.gradle.org,从国内访问这个地址速度很不稳定,首次构建时 Gradle 需要把整个发行版 zip 下载到本地,通常一百多 MB,网速差的时候下到一半就超时,于是就有了 "Could not install Gradle distribution from ... java.net.SocketTimeoutException" 这类报错。

第二种是依赖下载。Gradle 发行版装好之后,项目还需要从 Maven 仓库拉取各种依赖 jar,比如 androidx、springboot、各种插件。这部分慢的表现不一样,通常是在 BUILD 阶段卡住,日志里出现 "Could not resolve ..." 或者某个仓库地址反复重试。它跟发行版是两套下载通道,只改 distributionUrl 根本解决不了。

搞清楚这点之后,你的排查方向就很明确了:卡在 "Downloading...",就去处理发行版;卡在 "Resolve" 或依赖列表刷新,就去处理仓库。不要指望一个方案通吃。

1.2 判断自己卡在哪个环节的三个小技巧

先说最直观的:看 Android Studio 的 Build 窗口输出。日志里出现 "Downloading https://services.gradle.org/distributions/gradle-x.y-bin.zip",说明还在下发行版;出现 "Could not resolve com.example:some-lib:1.0.0",说明依赖解析卡了。这两行字能帮你省掉一半瞎折腾的时间。

第二个技巧是看本地缓存目录。发行版缓存在 ~/.gradle/wrapper/dists 下,依赖缓存在 ~/.gradle/caches/modules-2 下。如果 dists 目录里只有一个陌生的哈希文件夹,里面只有 .part 或者 lock 文件,那基本可以确定是发行版没下完;如果发行版目录已经完整了但项目还是慢,重点去看依赖缓存有没有正常增长。这个判断方法在 Windows、macOS、Linux 上都一样,只是用户目录位置不同。

第三个技巧是命令行验证。直接在项目根目录跑 ./gradlew --version,如果能很快输出版本信息,说明发行版已经就位,问题出在依赖;如果这条命令卡在下载阶段,那就是发行版没搞定。实测下来这个 check 非常快,几秒钟就能定位,比自己瞎猜准得多。

2. 第一招:把 distributionUrl 换成国内镜像

2.1 Gradle 发行版镜像地址怎么改

定位到发行版下载慢之后,最简单的办法就是换 distributionUrl。打开项目里的 gradle/wrapper/gradle-wrapper.properties,找到 distributionUrl 这一行,默认长这样:

distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists

services.gradle.org 的地址保持不变也可以,但实际下载速度完全看网络心情。国内几个大厂都有 Gradle 发行版镜像,地址格式几乎一样,就是把域名换一下。我用过的几个都验证过:

  • 阿里云:https://mirrors.aliyun.com/gradle/gradle-8.7-bin.zip
  • 腾讯云:https://mirrors.cloud.tencent.com/gradle/gradle-8.7-bin.zip
  • 华为云:https://mirrors.huaweicloud.com/gradle/gradle-8.7-bin.zip

以阿里云为例,修改后 distributionUrl 那一行变成:

distributionUrl=https\://mirrors.aliyun.com/gradle/gradle-8.7-bin.zip

注意 properties 文件里 URL 中的冒号要加反斜杠转义,否则解析会出问题。版本号和原文件保持一致,原来是 8.7 就写 8.7,原来是 8.5 就写 8.5,不要随便改,因为 gradle wrapper 的 jar 和项目构建配置通常是为特定版本准备的。还有 -bin 和 -all 的区别:-bin 就够了,-all 包含源码和文档,体积更大、下载更慢,没必要为了看源码多下载两百多 MB。

2.2 换完发行版镜像,依赖还是慢怎么办

发行版解决之后,如果首次构建还是很长时间,多数情况是依赖仓库的问题。默认的仓库顺序通常写在 settings.gradle 或 build.gradle 里,包含 google()、mavenCentral()、gradlePluginPortal(),这几个域名在国内访问速度一般,特别是 google() 偶尔会很慢。

解决办法是加入国内镜像仓库,并且把它们放在仓库列表最前面。具体来说,可以在 settings.gradle 的 dependencyResolutionManagement 里调整,比如:

dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/google' } maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } google() mavenCentral() } }

插件仓库也要单独处理,在 pluginManagement 里加上 gradle-plugin 镜像。很多项目发行版都下好了,却卡在插件解析上,就是因为这层仓库没配置。阿里云公共仓库已经聚合了 Maven Central 的内容,google 镜像单独配一个,插件镜像再配一个,基本能覆盖绝大多数依赖来源。

这里有个细节:如果项目里已经用 repositoriesMode.set(RepositoriesMode.PREFER_PROJECT),那子项目的 repositories 会优先,你可能需要去各模块的 build.gradle 里把镜像加上。我一般推荐在 settings.gradle 统一配置,避免每个模块都维护一份仓库列表。

3. 第二招:离线包 + 本地分发,彻底绕开网络

3.1 手动下载 Gradle 到本地,速度直接拉满

换镜像已经能覆盖大部分场景,但如果你所在网络环境连镜像都时好时坏,或者你就是不想每次都在 IDE 里干等,那就用离线包。这个方法也常被称为 Gradle offline distribution,核心是把 zip 下载这件事从 Gradle 手里抢过来,用浏览器、下载工具甚至在另一台网速好的机器上先把包拉下来。

具体操作分三步。第一步,从镜像站或官方地址把 gradle-8.7-bin.zip 下载到本地,比如 D:/tools/gradle/。第二步,把 gradle-wrapper.properties 里的 distributionUrl 改成 file 协议指向本地文件:

distributionUrl=file\:///D:/tools/gradle/gradle-8.7-bin.zip

第三步,重新运行构建。Gradle 看到 file 协议的 URL 就直接从本地 zip 解压安装,整个过程不碰网络,几秒钟就能完成发行版准备。

如果不想改项目文件,还有一个更隐蔽的玩法:手动把 zip 塞进 wrapper 缓存目录。Gradle 默认缓存路径是 ~/.gradle/wrapper/dists/gradle-8.7-bin/<哈希值>/,那个哈希是 Gradle 根据 distributionUrl 算出来的,不同地址对应不同目录。你可以先不管这个哈希,直接运行一次 ./gradlew 让它创建目录,然后立刻中断,再把 zip 放到对应的临时目录里,重新运行。这样做的原理是 Gradle 校验到 zip 已经存在且完整,会跳过下载直接解压。不过说实话,这个方法比改 distributionUrl 麻烦,我平时用得少,最多是在不想动版本控制文件的时候应急。

3.2 团队协作,内网共享一套 Gradle 和依赖缓存

离线包不仅自己能用,也很适合团队场景。新同事入职或者换电脑之后,最痛苦的就是重新下载整套工具链。所以我现在在团队里推广的做法是:内网放一个只读共享目录,把常用的 gradle zip、依赖缓存目录、init.gradle 全都放进去,谁要装环境自己拉。

具体来说,我会让新同事先设置 GRADLE_USER_HOME 指向一个本地的自定义目录(默认是 ~/.gradle),然后把老同事电脑上已经下好的 ~/.gradle 目录整体拷过去或者从共享盘拉取。注意不是运行中的拷法,直接在 IDE 关闭、没有任何 gradle 进程的时候拷贝,避免文件锁问题。拷完之后,wrapper/dists 里已经有所需的发行版,caches/modules-2 里已经有常用依赖缓存,新环境第一次构建会非常快。

如果团队项目版本统一,我建议固定 gradle-wrapper.properties 的版本并且把 distributionUrl 指向内网 HTTP 服务,比如:

distributionUrl=http\://192.168.1.100/gradle/gradle-8.7-bin.zip

这样每个人第一次构建都会从内网拉取,速度比外网快一个量级。团队里用 Nexus 私服的做法也类似,后面会细说。要注意的是,内网共享方案要提前搭好,别等大家都卡住了才想起来,那时候网络就成瓶颈了。

4. 第三招:依赖仓库也走本地缓存和私有化

4.1 用 init.gradle 全局替换仓库

依赖仓库的配置,前面提到可以在 settings.gradle 里改,但每个项目都要改就很烦。更省事的方法是写一个全局初始化脚本,放在 ~/.gradle/init.d/init.gradle 里。Gradle 每次构建都会自动加载这个脚本,对所有项目生效,相当于在全局层面把镜像仓库"注入"进去。

我实际的 init.gradle 内容大概是:

allprojects { repositories { maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/google' } maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } } } settingsEvaluated { settings -> settings.pluginManagement { repositories { maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } google() mavenCentral() gradlePluginPortal() } } }

这个脚本写好后,绝大部分项目的依赖解析都会优先打镜像,官方仓库作为后备。注意脚本里 allprojects 的作用对象是所有 Project,但 settings 阶段要用 settingsEvaluated 回调才能安全修改 pluginManagement。有些人在 init.gradle 里直接写 pluginManagement 会报错,就是因为时机不对。

一个小坑是,有些项目为了强制统一仓库,会在 settings.gradle 里设置 repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS),这时候 init.gradle 里的 allprojects 配置可能失效或报错。真遇到这种项目,还是去项目里改配置更靠谱,全局脚本不是万能的。

4.2 搭一个 Nexus 私服,团队缓存一劳永逸

init.gradle 解决的是"从外网镜像下载慢",但对于一个二三十人的团队,更严重的问题是每个人都在重复下载同一批依赖。我见过最多的场景:十个人同时第一次构建,内网带宽被占满,镜像再快也没用。这种情况下,私有仓库就是正解。

Nexus 是目前用得最多的制品库,安装不算复杂,装好后创建几个 proxy 类型的仓库,分别指向 mavenCentral、google 等远程源。然后让项目的仓库列表统一指向 Nexus 地址:

maven { url 'http://192.168.1.100:8081/repository/maven-public/' }

第一个同事下载依赖时,Nexus 从远程拉回来并缓存到本地;后续同事再请求同样的构件,Nexus 直接返回缓存,速度是局域网级别。而且 Nexus 还能和前面说的 Gradle 发行版 zip 一起托管,distributionUrl 也可以指向它,这样全公司的 Gradle 下载问题一次解决。

我自己搭过两套 Nexus,踩过的最典型的坑是 remote storage 配置了官方地址后连接超时导致首次拉取失败。解决办法是给 Nexus 配置合理的超时和重试参数,同时把远程仓库优先设为国内镜像,而不是官方源。另外,Nexus 的 blob store 默认在系统盘,依赖多了会占空间,建议提前挂载一个独立的数据盘。

如果你觉得搭 Nexus 太重,还有一个过渡方案:在项目里先使用 mavenLocal(),配合 gradle 的本地 publishToMavenLocal 把内网公共模块装进本地仓库。这个方案不适合管理第三方依赖,但对内部公共库很有效,成本几乎为零。

5. 第四招:Daemon、并行和超时参数调优

5.1 gradle.properties 里的几个关键参数

下载问题解决了大半之后,还有一个容易被忽略的软性因素:构建本身的并发策略。Gradle 构建默认的并行度不高,如果项目模块多,串行等待会让整体过程显得非常慢,虽然它和下载速度没有直接关系,但用户感知就是"Gradle 卡住"。

在项目根目录的 gradle.properties 里,我一般会加这几行:

org.gradle.daemon=true org.gradle.parallel=true org.gradle.caching=true org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8

org.gradle.daemon 保持 true,让 Gradle 守护进程常驻,避免每次构建都重新启动 JVM。org.gradle.parallel 让多个模块并行构建,模块多的项目这个提升非常明显。org.gradle.caching 开启构建缓存,第二次构建可以跳过很多任务。jvmargs 则根据机器内存调整,内存小的机器不要盲目加大,2GB 起步够用。

另外,如果你用了 Kotlin,可以在 gradle.properties 里单独设置 kotlin.daemon.jvmargs,给 Kotlin 守护进程分配足够内存,否则 Kotlin 编译很容易成为瓶颈。这些参数不会让你已有的下载失败自动变好,但会显著减少"下载完却还是慢"的挫败感,配合前面几招一起用效果才完整。

5.2 超时与重试配置,别让网络波动毁掉整次构建

还有一个容易踩坑的地方:Gradle 在内置 HTTP 客户端的超时时间比较保守,网络稍微一波动,一个大文件下载到一半就抛 SocketTimeoutException。Gradle 也提供了一些内部系统属性来调整这个行为,实测有效的是这两个:

systemProp.org.gradle.internal.http.socketTimeout=180000 systemProp.org.gradle.internal.http.connectionTimeout=180000

单位是毫秒,我这里设置的 180 秒。简单理解,connectionTimeout 是建立连接的最大等待时间,socketTimeout 是连接建立后每次读取数据的最大空闲等待时间。调大之后,对于偶尔抽风但总体可用的网络,能明显减少"下载中断重来"的情况。如果你的网络本来就稳定,保持默认也没问题,调太大反而会在网络完全不可用时让失败发现得更晚。

我个人的经验是:在下载发行版 zip 这种大文件时,超时配置和镜像源是配套使用的。如果没有镜像,单纯调大超时只会让失败来得更慢,该下不动的还是下不动;有了镜像,超时调大就成了兜底手段,网络小抖动不影响最终结果。

6. 实战排错:Gradle 下载常见的症状和排查顺序

6.1 常见报错速查表

下面这个表格是我在实际开发中遇到过的典型报错和对应的解决方向,先看症状,再对号入座,能省很多时间:

报错信息可能原因解决方向
Could not install Gradle distribution from ... java.net.SocketTimeoutException发行版下载超时、网络不稳定换国内镜像、手动下载 zip、调大超时
Download failed because not enough bytes were received下载被中断、接收字节数不足清理缓存后重新下载、换镜像、检查磁盘空间
Could not resolve gradle:gradle:8.7依赖仓库不可达或仓库顺序问题检查 repositories、配置镜像或 Nexus 私服
Android Studio importing Gradle project 太慢发行版加依赖双重下载叠加先放好发行版离线包,再配依赖镜像
一直卡在 Downloading ... 且进度不动官方源访问慢直接修改 distributionUrl 为镜像地址

需要提醒的是,网上搜索 Gradle 下载慢的时候,偶尔会混进来一些完全无关的报错,比如嵌入式烧录工具里的 "flash download failed"、浏览器下载器之类的内容,别被带偏。判断标准很简单:和 gradle、wrapper、maven 无关的报错信息,基本不属于 Gradle 这个坑。

6.2 我实际跑通一个干净项目的完整顺序

最后分享一套我在新电脑上配置环境、让一个完整 Android 项目跑通的顺序。这套流程适用于"从零到可以构建"的场景,每一步都有明确目的。

第一步,准备好 Gradle 发行版。先确认项目 gradle-wrapper.properties 里的版本,然后从镜像站下载对应的 zip,放在固定目录,并把 distributionUrl 改成 file 协议或内网地址。这一步解决的是发行版下载慢。

第二步,配置全局镜像。把前面说的 init.gradle 放到 ~/.gradle/init.d/ 目录,这样所有项目默认走国内镜像。这一步解决的是依赖下载慢。

第三步,打开 Android Studio,等待首次 Gradle Sync。观察日志:发行版阶段应该几秒完成,依赖解析阶段可能有少量首次下载,但速度应该接近镜像站带宽。如果还卡,就看卡在哪个 URL,再回上一节对照排查。

第四步,新同事环境准备。整机拷贝 GRADLE_USER_HOME 缓存目录,或者从内网共享盘拉取,避免每个新环境重新下依赖。

这套流程我实践过多次,正常情况下首次完整构建从原来十几分钟甚至直接失败,能缩短到五分钟左右,后续增量构建基本就是分钟级以内。需要注意的是,不要在多个 IDE 窗口同时打开同一个新项目做首次 Sync,那样会触发重复下载甚至文件锁冲突。

最后说一点实际体会。Gradle 下载慢这个问题,网上的方案确实很多,但真正解决问题的往往就是"换源 + 离线包 + 本地缓存"这三板斧。我自己的习惯是:固定项目常用的 Gradle 版本,提前把 zip 和依赖缓存都准备好,新机器到手直接复制,比临时找镜像快得多。另外也别迷信单一技巧,不同网络环境差异很大,把这几个方法组合起来用,先定位卡点再动手,基本就不会再被 Download 卡到怀疑人生了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询