用 Android Studio 做安卓开发的人,十个里有九个经历过这样的场景:项目一打开,右下角 Gradle 开始转圈,仔细一看日志,卡在“Downloading https://services.gradle.org/distributions/gradle-8.2-bin.zip”,等了十分钟还是百分之几;要么就是 sync 的时候刷了一屏红色错误,点开一看全是 “Could not resolve androidx.appcompat:appcompat:1.6.1”,但其实这个包确实存在,也不是版本写错了,就是拉不下来。这些问题的根源,说白了就是 Gradle 默认下载源在国内访问不稳定。用国内镜像把下载地址替换掉,是解决这个问题的核心手段,也是今天我要展开说的内容。
1. 每次构建卡半天:先把 Gradle 的两个独立下载阶段拆明白
很多人在“Gradle 国内镜像”这个问题上绕圈子,不是因为教程少,而是因为没搞清楚 Gradle 的“下载慢”其实包含两个完全不同的阶段:一个是下载 Gradle 发行包本身,另一个是下载项目依赖的第三方库。两个阶段用的配置文件、解决方案完全不一样。混在一起排查,经常会出现“改了 A 没解决 B”的情况,非常浪费时间。
1.1 发行包:gradle-wrapper.properties 里的 distributionUrl 决定一切
先说发行包。每一个 Android Studio 项目,根目录下都会有一个 gradlew 脚本,以及 gradle/wrapper/gradle-wrapper.properties 文件,这套机制叫 Gradle Wrapper。它的作用是把项目的 Gradle 版本固定下来,让所有开发者和 CI 机器用同一个版本构建,避免“我机器上能过,你机器上过不了”的环境不一致问题。
gradle-wrapper.properties 里最关键的一行是:
properties复制distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
第一次打开项目或执行构建时,Gradle Wrapper 就会根据 distributionUrl 去下载 gradle-8.2-bin.zip。只要本地缓存里没有这个版本,它就会重新下载。这个压缩包通常 100MB 到 200MB,从默认的官方源下载,在国内经常只有几 KB/s,甚至直接超时。项目多、版本多的时候,每切换一个项目就要重新经历一次这种等待,非常消耗耐心。
1.2 依赖库:仓库地址写在 settings.gradle 而不是 gradlew 里
第二个阶段是项目依赖下载。项目里用到的 AndroidX、Compose、Glide、OkHttp 这些第三方库,全部要从仓库拉取。仓库地址定义在项目根目录的 settings.gradle(新版项目)或者 build.gradle(老版项目)里,最常见的是:
groovy复制repositories {
google()
mavenCentral()
}
google() 背后是 https://dl.google.com/dl/android/maven2/,mavenCentral() 背后是 https://repo.maven.apache.org/maven2/。这两个源在国内的访问质量时好时坏,坏的时候 sync 到一半就报错,提示某个库无法解析。很多人以为是依赖版本问题,其实是网络问题。
把这两个阶段区分清楚,接下来的内容就顺着两条线展开:先解决发行包下载慢,再解决依赖仓库下载慢,最后把换镜像后常见的报错整理成排查清单。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 发行包下载慢:三种落地方式解决 distributionUrl 的困境
发行包下载慢的解决办法,核心就一句话:让 distributionUrl 指向国内可以快速访问的镜像地址。下面按实操路径给出三种落地方式,从简单到省事依次排列。
2.1 单项目改法:把 distributionUrl 指向腾讯云或华为云镜像
找到项目根目录下的 gradle/wrapper/gradle-wrapper.properties,把 distributionUrl 替换为腾讯云或华为云的 Gradle 发行包镜像地址:
- 腾讯云 Gradle 镜像目录:https://mirrors.cloud.tencent.com/gradle/
- 华为云 Gradle 镜像目录:https://repo.huaweicloud.com/gradle/
比如项目原来的版本是 8.2,替换后是这样:
properties复制distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.2-bin.zip
改完保存,再重新 Sync 项目。这里有两个容易踩坑的细节。
第一,URL 里的冒号和斜杠需要转义。Properties 文件把冒号、等号都当作分隔符,不转义会导致 Wrapper 解析 URL 失败。Android Studio 的编辑器一般会自动转义,但如果你用记事本或命令行直接改,十有八九会漏。
第二,只替换域名部分,不要动版本号和 zip 类型,更不要从 bin 改成 all。distributionUrl 里的文件名必须和原来保持一致。如果你手滑改了版本号,全团队的 Gradle 版本会被强制改变,随后可能触发一堆插件兼容问题。
2.2 全局改法:手动下载并覆盖本地 Wrapper 缓存
如果你不想每个项目都改一遍,可以走“本地缓存覆盖”路线。Gradle Wrapper 下载后的文件会缓存在本机用户目录的固定位置:
text复制~/.gradle/wrapper/dists/
你需要先从镜像目录里手动下载对应版本的 zip 包,比如 gradle-8.2-bin.zip,然后把它放到 dists 目录对应的版本文件夹下。注意文件夹按版本区分,而且有 hash 后缀,不同项目可能使用不同的 hash 目录,放错位置不会被识别。
还有一个更直观的办法:打开 Android Studio 的 Settings -> Build, Execution, Deployment -> Build Tools -> Gradle,在 Gradle distribution 一栏,把选项从 Wrapper 切到 Local Gradle distribution,再指定本地已解压的 Gradle 目录。这种方式完全不触发网络下载,适用于网络条件特别差的环境。缺点是每台机器都要手动准备本地 Gradle,多台机器协作时维护成本高,所以更适合 CI 服务器或一次性构建环境。
2.3 三个配置文件各自职责要分清,配错位置等于白忙
有人会在 gradle.properties 里配置镜像地址,折腾很久发现一点效果没有。这里必须把三个文件的职责讲清楚:
- gradle-wrapper.properties:控制 Gradle 发行包下载地址,就是 distributionUrl。
- settings.gradle:控制依赖仓库和插件仓库,也就是 google()、mavenCentral()、maven { url ... } 这些。
- gradle.properties:控制 Gradle 构建进程的 JVM 参数、内存分配、缓存行为,不负责下载源。
打个比方:gradle-wrapper.properties 是“去哪个官网下安装包”,settings.gradle 是“去哪个超市买菜”,gradle.properties 是“做饭时灶台火开多大”。火开得再大,菜市场没开门,照样做不了饭。
3. 依赖仓库拉不动:settings.gradle 镜像源替换与选型
发行包下载解决后,另一个高频场景就是依赖仓库解析失败。这一节专门讲怎么在 settings.gradle 里配置各家的国内镜像源。
3.1 阿里云系列镜像:国内最常用的首选配置
阿里云 Maven 是国内兼容性比较好的镜像源,对 Google Maven 的同步覆盖也相对完整。Android 项目常用的是这几个仓库地址:
| 用途 | 地址 |
|---|---|
| 替代 mavenCentral() | https://maven.aliyun.com/repository/central |
| 替代 google() | https://maven.aliyun.com/repository/google |
| Gradle 插件仓库 | https://maven.aliyun.com/repository/gradle-plugin |
| 聚合仓库(含中央仓库等) | https://maven.aliyun.com/repository/public |
适合新版 Gradle 的 settings.gradle 配置如下:
groovy复制pluginManagement {
repositories {
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven { url 'https://maven.aliyun.com/repository/public' }
gradlePluginPortal()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
mavenCentral()
}
}
配置里保留 mavenCentral() 是有意义的。阿里云镜像偶尔会差某一个冷门版本,官方源作为兜底可以提高解析成功率。但要注意仓库顺序:Gradle 会按顺序依次尝试,如果 mavenCentral() 排在最前面,它可能先去访问官方源并超时,然后再往后走。所以镜像地址要放在前面,官方源放最后。
3.2 腾讯云、华为云镜像:主源不稳定时的备选方案
阿里云也不是万能。某些比较新的库版本在阿里云同步不及时,或者公司网络对某些域名有限制,这时候可以切到腾讯云或华为云。
腾讯云的 Maven 聚合仓库配置:
groovy复制repositories {
maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/maven-public/' }
maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/google/' }
}
华为云的 Maven 聚合仓库配置:
groovy复制repositories {
maven { url 'https://repo.huaweicloud.com/repository/maven/' }
maven { url 'https://repo.huaweicloud.com/repository/google/' }
}
如果项目里用到 Gradle 插件,插件仓库也可以用:
groovy复制maven { url 'https://mirrors.cloud.tencent.com/nexus/repository/gradle-plugins/' }
maven { url 'https://repo.huaweicloud.com/repository/gradle-plugins/' }
这三家镜像对常用 Android 库的覆盖率都够用,差别主要在同步速度和偶发连接问题。我的习惯是阿里云做主力,腾讯云做备选,华为云兜底。切换成本很低,无非是改几行 URL,但项目 Sync 突然失败时,切一个源往往就能恢复。
3.3 Kotlin DSL 项目写法:settings.gradle.kts 换源有区别
新项目越来越多地用 Kotlin DSL,也就是 settings.gradle.kts 和 build.gradle.kts。这种写法下,仓库配置表面看起来差不多,但语法略有不同:
kotlin复制pluginManagement {
repositories {
maven(url = "https://maven.aliyun.com/repository/google")
maven(url = "https://maven.aliyun.com/repository/gradle-plugin")
maven(url = "https://maven.aliyun.com/repository/public")
gradlePluginPortal()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
maven(url = "https://maven.aliyun.com/repository/google")
maven(url = "https://maven.aliyun.com/repository/public")
maven(url = "https://maven.aliyun.com/repository/gradle-plugin")
mavenCentral()
}
}
相比 Groovy 的写法,Kotlin DSL 里的 URL 是普通字符串,不需要像 Properties 文件那样转义,写起来舒服很多。但要注意,Kotlin DSL 对类型要求更严格,少写 url = 或者打错引号都可能直接编译失败。
3.4 冷门库、JitPack 与动态版本:三个容易误判的仓库问题
配置镜像之后仍解析不到依赖,不一定是镜像问题,先排查这三个原因。
第一,JitPack。如果项目依赖的是 GitHub 项目直接打包的库,例如:
groovy复制implementation 'com.github.username:library:1.0
