ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Android SDK代理与镜像配置:告别下载慢和Gradle卡顿

Android SDK代理与镜像配置:告别下载慢和Gradle卡顿

简介:许多Android开发者在下载SDK组件时都会遇到速度极慢或连接失败的痛点,这份文档正是针对该问题的实操指南。内容以清晰步骤讲解如何在Android Studio的SDK Manager中配置HTTP代理,覆盖自动检测与手动设置两种模式,并给出东软、阿里云、腾讯云等国内镜像站的地址、端口及身份验证信息填写方法。配置完成后,不仅SDK本体下载提速,Gradle插件、Google服务框架等依赖的获取也会更稳定,有效减少开发环境搭建中的等待与报错。资源为单个docx文档,约102KB,步骤完整、便于随查随用。目前已有861人学习下载,特别适合受网络限制的Android初学者与需要优化构建环境的中级开发者。文档同时提醒代理需根据网络条件动态调整,并提供多镜像备选思路,实用性较强。

1. SDK 设置代理:下载慢不是玄学,是直连路径没走对

做过 Android 开发的人多半有过这种经历:新建工程后 Sync 一次,Gradle 卡在下载依赖上,SDK Manager 里某个平台版本下载到一半就报错,重试三五次才成功,甚至放一晚上还在转圈。SDK 设置代理这件事,说白了就是把 SDK Manager 的下载请求从默认的官方远端切到国内镜像,让文件从更近的路径到达本地。我第一次配好之后,原来要下半个小时的 build-tools 变成几分钟,从那以后就再没裸连过官方源。这篇文章适合网络环境一般、被 SDK 组件下载卡住的人,也适合在团队里要给多名开发者统一配置环境的场景。整理一下思路和参数,后面直接照着操作就行。

2. 代理与镜像:为什么同一份 SDK 走不同路径差十几倍

2.1 SDK Manager 的下载链路:从官方仓库到本地文件

Android SDK Manager 的工作方式并不复杂。它维护了一个组件清单,清单里记录了每个平台版本、build-tools、platform-tools 对应的压缩包地址和校验值。你点下安装按钮后,SDK Manager 通过 HTTPS 请求把这些压缩包下载到本地,再解压到 SDK 根目录的对应文件夹。问题出在默认远端地址上:官方源的 CDN 节点很多部署在海外,跨网络访问时丢包、断连就成了常态。

SDK Manager 在设计上允许你修改下载源头,但它分两个层次:一种是通过 HTTP Proxy 转发请求,SDK Manager 仍然访问官方地址,只是本地网络经由代理服务器中转;另一种是替换整个仓库镜像源,SDK Manager 直接向镜像站点请求文件。这两种做法在 Android Studio 的图形界面里被合并到了同一个设置面板,容易混淆,后面会专门解释。

实际开发中,经常还有第三个层次的问题:Gradle 自动下载依赖时也会走自己的网络通道。SDK Manager 配好了代理,Gradle 却可能仍然直连,因为 Gradle 的 JVM 进程不一定继承 SDK Manager 的网络配置。这是新手踩得最多的坑,我会在第 4 章单独展开。

2.2 HTTP 代理 vs HTTPS 代理 vs 镜像源:三种选型的取舍

先看概念,不然配置的时候不知道填什么。HTTP 代理是一个转发服务,你告诉 SDK Manager “先连这个代理,再由它去请求目标地址”。代理收到请求后把它转发到 Google 官方仓库,拿到文件再回传给你。这类代理的优点是 SDK Manager 无需改动请求目标,缺点是代理服务器的带宽和并发能力决定了你的下载速度,而且官方仓库路径仍然存在跨网问题,代理服务器也得能稳定连到海外才行。

HTTPS 代理与 HTTP 代理的区别在于隧道协议,它用 CONNECT 方法建立一条加密隧道,SDK Manager 和目标服务器之间传输的数据经过代理但代理无法窥探内容。Android Studio 里填的代理地址如果使用 443 端口,通常走的就是 HTTPS 代理。

镜像源是完全不同的思路。某些高校或开源社区会定期把 Android SDK 的官方仓库同步一份到自己的服务器上,文件内容不变,但访问路径从海外变成了国内。SDK Manager 在下载时会把域名替换成镜像域名,本质上就是换了一个下载源头。镜像源的优势是不依赖代理的转发能力,劣势是同步有时间差,而且部分镜像只同步了常用组件,冷门版本可能缺失。

三种选型用一个表格来对比:

选型配置位置请求目标速度瓶颈适用场景
HTTP 代理HTTP Proxy 面板官方仓库代理服务器带宽与到海外的链路临时加速,代理质量好时通用
HTTPS 代理HTTP Proxy 面板官方仓库代理服务器到海外的链路质量对安全要求高,官方源仍可访问
镜像源仓库地址替换镜像服务器镜像服务器带宽与你的本地链路国内长期开发,官方源不稳定

选择建议:如果你是个人开发,直接选镜像源,配置简单,效果明显;如果你在公司内网,网络出口统一走代理,那就配置 HTTP 代理;两者都能用的时候,我倾向于镜像源优先,因为它的下载行为更可控,不会因为代理服务器临时抽风导致整个构建失败。

2.3 镜像站点的可靠性判断:版本滞后、完整性与同步周期

镜像源不是随便填一个就能用,选错镜像比不配置还难受。判断一个镜像值不值得用,主要看三个维度:同步周期、组件完整度、协议支持。

同步周期指的是镜像仓库多久从官方源拉一次新文件。Android SDK 的组件更新不算频繁,但每年会有几次大版本更新,如果镜像停留在半年前的版本,新项目需要的 compileSdk 版本就拉不到。更隐蔽的问题是增量更新造成文件损坏,所以镜像站点一般会保留一份校验清单,SDK Manager 下载后校验失败时会提示错误。

组件完整度最容易被忽视。很多镜像为了节省存储只同步 platform 和 build-tools,platform-tools 或 emulator 这类体积较大的包可能缺席。你配置好代理后下载 platform 很顺利,但下载 emulator 时 404,这种表现通常会让人误以为是网络问题。

协议支持是指镜像提供 HTTP 还是 HTTPS 访问。有些老镜像只有 HTTP,而 Android Studio 默认勾选了 “Force https://” 选项,两者冲突时会出现连接失败。看到这个选项的时候要留意,不要无脑勾选。

我一般会先下载一个体积比较小的组件做测试,比如 platform-tools,看它能否完整下载并校验通过,再继续安装大件。用镜像最忌讳的是配置完之后不验证,等 Sync 项目时才发现问题,排查成本一下就上去了。

3. Android Studio 图形界面配置:SDK Manager 的八步操作

3.1 打开 SDK Manager 的两种路径

Android Studio 里进入 SDK Manager 有两个常用入口。第一个是顶部菜单栏 Tools → SDK Manager,也就是项目正文里提到的路径;第二个是打开一个项目后,点击右侧工具栏的 SDK Manager 图标,效果相同。两者都会打开同一个对话框,里面包含 SDK Platforms、SDK Tools、SDK Update Sites 三个标签页。

需要区分的是,Tools 菜单在早期版本的 Android Studio 里是顶部主菜单,新版可能折叠到了更多菜单里,但 SDK Manager 这个入口一直都在。打开 SDK Manager 后,左下角会有一个 “SDK Tools” 标签页,这个标签页管理的是 Android SDK 的各种命令行工具和平台组件,代理设置入口就藏在这个标签页的右上角。

点击 SDK Tools 标签页右上角的齿轮图标,会弹出 SDK Manager Settings 窗口。这个窗口里集中了 HTTP Proxy 和仓库源配置两类选项,操作逻辑虽然简单,但填错参数的结果比较隐蔽,值得逐一说明。

3.2 HTTP Proxy 设置面板参数详解

SDK Manager Settings 窗口里,HTTP Proxy 区域有三个核心控件。最上面的单选按钮是 “Auto-detect proxy settings”,选择它后 Android Studio 会尝试读取系统代理设置,自动填入代理地址。这个选项适合公司电脑已经配置好系统代理的情况,但并不适合大多数国内个人开发场景,因为系统代理通常是关着的,自动检测的结果往往是 “No Proxy”,等于没配置。

第二个单选按钮是 “Manual proxy configuration”,也就是手动配置。选中后会出现 Host、Port 两个输入框,以及一个 “Authentication” 区域。Host 填代理服务器的域名,Port 填服务端口。需要注意,这里的 Host 既可以是真正的 HTTP 代理服务器地址,也可以是镜像站点的域名,区别在于你是否额外勾选下面的选项。

如果选择的是镜像源,记得在下方勾选 “Force https://… sources to be fetched using http://”。这个选项的含义是让 SDK Manager 把请求协议从 HTTPS 降级为 HTTP,以便和只支持 HTTP 的镜像兼容。勾选它会降低传输安全性,但在使用老镜像时这是必要的。如果镜像本身支持 HTTPS,就不需要勾选。

Authentication 区域的 Username 和 Password 只有在你使用的代理服务器要求身份验证时填写。大多数公共镜像不需要,留空即可。填写了它们之后,SDK Manager 在每次请求时都会携带认证信息,如果代理端认证失败,错误提示往往比较含糊,后面避坑章节会说到这个问题。

配置完成后点 Apply 或 OK,设置并不会立即对所有正在运行的任务生效。如果你之前已经发起了下载任务,需要取消重试才能让新设置生效,修改代理后再点击下载列表里的组件,SDK Manager 会重新建立连接。

3.3 配置生效后的验证:看下载日志与组件状态

这一步最容易跳过,但不做验证的代理配置和没配置差别不大。确认代理生效的方法很简单:在 SDK Manager 里安装一个组件,观察底部状态栏的下载速度和日志输出。通常情况下,镜像源下载速度能稳定在几 MB/s 以上,而官方源直连可能只有几十 KB/s,差异非常明显。

更精确的做法是查看 SDK Manager 的日志文件。在 Android Studio 的 Help → Show Log in Explorer 里可以打开 IDE 日志目录,搜索sdk相关的日志记录。SDK Manager 发出的每个 HTTP 请求都会记录目标 URL,从 URL 的域名就能判断请求是否走了镜像或代理。如果 URL 仍然是 dl.google.com,说明代理没有生效。

验证时还要留意组件状态的显示。下载完成后,组件前会显示已安装的勾选标记,但如果下载过程中出现校验失败,组件状态会保持未安装,旁边会有红色或黄色的警告图标。这种情况通常是文件不完整或镜像源同步异常,需要换一个镜像源再试。

我在配置时习惯先只勾选一个体积在 50 MB 左右的组件做测试,比如某个版本的 build-tools。这个体积足以暴露速度和稳定性问题,又不会像 platform 那样动辄几百 MB,失败重试的成本低。测试通过后再批量安装其他组件,比一次性勾选一大堆然后看着失败列表一个个排查要高效得多。

4. 命令行与 Gradle 层配置:把代理固化到工程

4.1 sdkmanager 命令行代理:--proxy 参数与环境变量

图形界面配置只对 Android Studio 本身生效,很多团队搭建 CI 环境时依赖的是命令行工具 sdkmanager,它不会读 Android Studio 的设置。sdkmanager 位于 SDK 根目录的 cmdline-tools 子目录里,它自己有一套代理参数,最常用的方式是追加--proxy和--proxy_host、--proxy_port参数。

sdkmanager --list --proxy=http --proxy_host=mirrors.example.edu.cn --proxy_port=80

这段命令的含义是让 sdkmanager 通过mirrors.example.edu.cn的 80 端口访问仓库,并列出可安装的组件列表。--proxy=http指定代理类型,其他可选值是https和socks,具体取决于镜像或代理服务支持的协议。执行成功后,命令输出的组件版本列表会明显加快返回速度,这就是代理生效的信号。

每次安装组件都带这三个参数比较繁琐,所以我会把参数写入环境变量。sdkmanager 除了命令行参数,还支持通过ANDROID_SDK_HOME目录下的配置文件读取代理,但我实测下来最稳妥的做法是把它包成脚本,避免环境变量在多版本 Java 工具链之间传递时被覆盖。

4.2 gradle.properties 里的 systemProp 代理配置

Gradle 是另一个独立的网络消费者。它下载依赖时同样可能直连官方仓库,这在国内环境里经常表现为 Sync 阶段卡在 “Downloading gradle-x.x.zip” 或某个依赖包长时间不变。Gradle 的代理配置写在工程根目录的 gradle.properties 文件里,使用 systemProp 前缀:

systemProp.http.proxyHost=mirrors.example.edu.cn systemProp.http.proxyPort=80 systemProp.https.proxyHost=mirrors.example.edu.cn systemProp.https.proxyPort=80 systemProp.http.nonProxyHosts=localhost|127.0.0.1|*.example.com

这段配置的关键点在于 http 和 https 要分别设置,如果只写了 http 的代理,走 HTTPS 协议的依赖请求仍然直连。nonProxyHosts是用来排除内网地址的,如果你的工程同时依赖公司内网仓库,必须把内网域名加进这个列表,否则内网依赖也会被强制走公网代理,导致内网请求失败。

在项目级的 gradle.properties 里配置代理会影响所有使用该工程的机器,包括 CI。如果只是本机开发想临时加速,建议把同样的配置写到~/.gradle/gradle.properties用户级文件里,作用范围只覆盖当前用户,不会污染工程配置。两种文件使用的键名完全一致,Gradle 会自动合并,用户级优先级低于项目级。

4.3 配置优先级冲突:Studio、命令行与 Gradle 谁说了算

这三个层面的代理配置并行存在时,冲突是必然的。Android Studio 的 SDK Manager 设置只影响 SDK 组件的下载,Gradle 的 systemProp 只影响 Gradle 的依赖解析,sdkmanager 的命令行参数只影响它自己发起的请求。它们互不共享,所以不存在一个全局开关,需要分别确认。

最常见的一种优先级误区是:在 Android Studio 里配好了代理,就认为整个工程构建都能加速,结果 Sync 阶段照样慢。原因就在于 Gradle 进程是独立 JVM,根本不读 Android Studio 的网络设置。反过来,把 gradle.properties 配好了,SDK Manager 的组件安装还是会走默认网络,因为 SDK Manager 是 IDE 插件体系里的另一套逻辑。

理解了这一点,排查顺序就清晰了:先确认卡住的是哪一层,再针对那一层做配置。用 Gradle 带动画卡住就是依赖下载问题,用 SDK Manager 装组件卡住就是本配置的问题。还有一个细节是 grading 构建时org.gradle.jvmargs里的系统属性优先级高于 gradle.properties 的 systemProp,如果你在 jvmargs 里写了代理参数,会覆盖 systemProp 配置。我不建议在 jvmargs 里设代理,它不够显式,后面维护的人很难找到来源。

5. 避坑记录:代理设置失败的几种典型现象

5.1 镜像地址能 ping 通,下载却报 403

现象:配置镜像地址后,SDK Manager 能正常加载组件列表,但下载具体文件时报 403 Forbidden。换个组件再试,错误依然存在。

原因:403 不是网络不通,而是服务器拒绝了请求。多数镜像站点会对某些文件的下载路径做防盗链校验,或者只允许特定 User-Agent 访问。SDK Manager 发起的请求 Header 相对固定,某些镜像基于客户端类型做了拦截。另一个常见原因是镜像目录结构不完整,请求路径指向了服务器上不存在的资源,返回 403 而不是 404。

解决:先确认镜像是否完整支持 SDK Manager 的访问方式,部分镜像只提供 HTTP 访问,需要取消勾选 Force https 选项。其次尝试更换镜像源,不同镜像的同步机制不同,能成功加载列表不代表能正常下载所有文件。我通常会在浏览器里直接访问镜像的文件目录,确认所需组件确实存在,再回到 SDK Manager 操作。如果确认是防盗链问题,就只能更换源,不值得在这种镜像上花时间。

5.2 代理配置后组件列表加载成功,下载速度仍然很慢

现象:SDK Manager 设置面板里代理配置没有问题,组件列表也加载出来了,但下载速度仍然只有几十 KB/s,与预期不符。

原因:列表加载走的是镜像访问,速度快;但实际下载时 SDK Manager 可能发出了重定向请求,把文件指向了官方原始地址。部分镜像只同步列表文件,不托管实际的大体积压缩包,或者镜像配置了 CDN 回源,你访问的节点仍然是远端节点。这种情况下从日志看到的请求 URL 起初是镜像域名,跟随重定向后变成了官方域名。

解决:查看 SDK Manager 的日志文件,确认最终下载请求的 URL 是否还停留在镜像域名上。如果出现了重定向,说明这个镜像的加速能力有限,换一个支持文件直存的镜像。在镜像选型时,优先选择直接提供完整压缩包下载路径的站点,不要选只同步清单的轻量镜像。

5.3 Force https 勾选后证书校验失败

现象:配置老镜像后勾选了 Force https 选项,结果 SDK Manager 在获取组件列表时报证书相关错误,提示连接失败或证书不受信任。

原因:Force https 选项的实际作用是让 SDK Manager 使用 HTTP 协议,而不是强制 HTTPS。如果填写镜像地址时仍然写的是https://开头的地址,并且勾选了这个选项,SDK Manager 的请求方式会与服务器的协议要求冲突。更复杂的场景是镜像本身的证书链不完全,Java 运行时校验时无法信任该证书。

解决:确认填写地址时希望走 HTTP 地址时不要加https://前缀。如果镜像支持 HTTPS,不要勾选 Force 选项。关于证书不受信任的问题,在开发机上可以将镜像证书导入到 Java 的 cacerts 证书库,但不建议在生产环境长期使用这种手段,本质上是降低了校验强度。更合理的做法是更换一个证书链完整的镜像源,从源头避免这个问题。

5.4 缓存残留导致换镜像后仍在使用旧文件

现象:从镜像 A 换到镜像 B 之后重新下载某个组件,SDK Manager 的下载速度很快,但安装后发现组件版本或文件内容仍是旧的。

原因:SDK Manager 有本地缓存机制,已下载完成的文件会存放在 SDK 根目录的.temp或缓存目录中。更换镜像源后,如果组件版本号相同,SDK Manager 会复用本地缓存,跳过下载。版本号未变化时,镜像 B 的文件与缓存中损坏或过期的文件无法区分。

解决:在更换镜像后,如果怀疑缓存残留,可以手动删除 SDK 根目录下的缓存文件,或者清理.temp文件夹。由于 SDK Manager 没有提供清理缓存的按钮,这是一个纯手工操作。我在更换镜像后会强制让 SDK Manager 重新下载一次 build-tools,确认文件大小和更新时间都是新的,再继续其他安装操作。

6. 进阶技巧:把代理配置固化成幂等脚本,顺带做下载链路自检

代理配置这种操作用一次很简单,但每次重装系统、更换开发机都要手动走一遍就很烦。我后来写了一个脚本,把 SDK Manager 的代理参数和下载链路自检合到一起,跑一次就能确认配置是否可用。

#!/usr/bin/env bash SDK_MANAGER="${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" MIRROR_HOST="mirrors.example.edu.cn" MIRROR_PORT="80" if [ ! -f "$SDK_MANAGER" ]; then echo "sdkmanager not found, check ANDROID_HOME" exit 1 fi "$SDK_MANAGER" --list \ --proxy=http \ --proxy_host="$MIRROR_HOST" \ --proxy_port="$MIRROR_PORT" \ 2>&1 | head -n 20 if [ $? -eq 0 ]; then echo "proxy works for sdkmanager" else echo "sdkmanager proxy failed" exit 2 fi

脚本的核心逻辑很直接:先检查 sdkmanager 的路径是否存在,再通过镜像地址拉取组件列表,只输出前 20 行用于确认连接性。退出码 0 表示链路通,非 0 表示需要检查网络或镜像状态。这里的head -n 20是防止组件列表太长刷屏,实际执行时输出去掉管道可以看到完整列表。

另外,包一层 Gradle 的代理校验也很有必要。把下面这段脚本加进项目的初始化脚本,每次构建前做一次快速连通性测试:

curl -s -o /dev/null -w "%{http_code}" \ --proxy "http://mirrors.example.edu.cn:80" \ "https://repo.maven.apache.org/maven2/"

以上命令通过 curl 模拟 Gradle 的代理连接,返回 200 或 302 说明代理链路可用,返回 000 说明连接被重置或拒绝。我会在 CI 环境的准备阶段跑这两段检查,fail fast 比构建到一半才发现网络问题省太多时间。

从那以后我每次都强制走一遍这个脚本,确认 SDK Manager 和 Gradle 两层的网络链路都通了才开始干活。新电脑装环境的时间从半天缩短到一小时,这玩意儿真的救了不少次。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进