← 返回博客列表

Flutter 与 pub.dev 依赖拉不下来:flutter pub get 超时、SDK 下载失败与镜像变量全解

2026-10-11 · 刺猬VPN

新建一个 Flutter 项目,执行 flutter create 之后的第一步往往就停住了:终端显示「Running "flutter pub get" in my_app...」然后再无动静,几分钟后吐出「Got socket error trying to find package xxx at https://pub.dev」或者「SocketException: Connection timed out」。也有人卡得更早,刚解压 SDK 执行 flutter doctor,就停在「Downloading Dart SDK from Flutter engine」或「Downloading Material fonts」。好不容易包拉下来了,flutter run 又停在「Running Gradle task 'assembleDebug'...」十几分钟。

这三处卡住的原因各不相同。SDK 与引擎产物来自 storage.googleapis.com,Dart 包来自 pub.dev 及其背后的存储,Gradle 依赖来自 Google Maven 与 Maven Central。镜像变量只能管前两段,Gradle 要单独配置;而 Dart 命令行读的是环境变量里的代理,不一定跟随系统代理。把三段分开处理,比反复删缓存重试有效得多。

三段下载分别走哪里

这张表说明了一件事:Flutter 的「依赖下载失败」不是一个问题,而是五六个主机的问题。镜像变量只覆盖引擎产物和 pub 包两段,设置之后 Gradle 依然走官方仓库。所以排查时先看终端停在哪一行,再决定改哪一处,而不是把能找到的变量全部贴进环境。

下载内容默认主机可用镜像变量典型报错
Flutter SDK 源码github.com/flutter/flutter无,可直接下压缩包git clone 中断
引擎与 Dart SDK 产物storage.googleapis.comFLUTTER_STORAGE_BASE_URLDownloading Dart SDK 卡住
pub 包索引与归档pub.devPUB_HOSTED_URLGot socket error trying to find package
Android Gradle 依赖dl.google.com、repo.maven.apache.org需改 Gradle 仓库配置Could not resolve com.android.tools.build:gradle
Gradle 本体services.gradle.org改 distributionUrlException in thread main 下载超时
iOS CocoaPodscdn.cocoapods.org、github.com改 Podfile 的 sourcepod install 卡在 Analyzing dependencies

从卡住到能跑:分步操作

  • 第一步:先把网络线路准备好。安装刺猬VPN,自定义用户名和密码注册,不需要邮箱和手机号,连上后先用浏览器打开 pub.dev 和 storage.googleapis.com,两个都能打开再回到终端。免费节点永久免费、不限流量、不限速,够用来判断问题是不是出在网络;
  • 第二步:确认终端能用上线路。Dart 与 Flutter 命令行读取环境变量 HTTP_PROXY、HTTPS_PROXY 与 NO_PROXY,未必跟随系统代理。Windows PowerShell 里用 $env:HTTPS_PROXY 设置,macOS 与 Linux 写进 ~/.zshrc 或 ~/.bashrc,NO_PROXY 至少写上 localhost,127.0.0.1,否则调试时连本机模拟器也会绕出去;
  • 第三步:执行 flutter doctor -v,看每一项的详细输出。停在 Downloading 开头的行,是引擎产物没下完;显示「Android toolchain」有叉,是 SDK 路径或许可证问题,与 pub 无关,处理方法见 Android SDK 那一篇;
  • 第四步:引擎产物下载失败时,删除 Flutter SDK 目录下 bin/cache 文件夹后重新执行 flutter precache。只删 cache,不要删整个 SDK,否则还要重新 clone;
  • 第五步:进入项目目录执行 flutter pub get。若仍报 socket error,用 dart pub get --verbose 看最后一次请求的完整地址,确认是索引请求失败还是归档文件下载失败;
  • 第六步:依赖解析失败而不是网络失败时,报错会写「Because my_app depends on xxx which requires SDK version」,这是版本约束冲突,改 pubspec.yaml 的版本号或执行 flutter pub upgrade --major-versions,与线路无关;
  • 第七步:缓存损坏时执行 dart pub cache repair,它会重新下载缓存里每一个包。缓存目录在 Windows 是 %LOCALAPPDATA%\Pub\Cache,macOS 与 Linux 是 ~/.pub-cache;
  • 第八步:Android 端停在 assembleDebug 时,打开 android/gradle/wrapper/gradle-wrapper.properties 看 distributionUrl 指向的 Gradle 版本,确认 services.gradle.org 能访问;Gradle 不读 HTTPS_PROXY,要在 android/gradle.properties 里写 systemProp.https.proxyHost 与 systemProp.https.proxyPort;
  • 第九步:全部通过后执行 flutter run,首次构建较慢属于正常,第二次会快很多。

按卡住的那一行排查

  • Waiting for another flutter command to release the startup lock:上一个 flutter 进程没退出,结束所有 dart 与 flutter 进程,必要时删除 bin/cache/lockfile 再试;
  • Downloading Dart SDK from Flutter engine 卡住:storage.googleapis.com 不通,确认线路后删 bin/cache 重下,或临时设置 FLUTTER_STORAGE_BASE_URL 指向镜像;
  • Got socket error trying to find package:pub.dev 请求失败,检查 HTTPS_PROXY 是否在当前终端生效,用 echo 打印一次变量确认;
  • HandshakeException 或 CERTIFICATE_VERIFY_FAILED:中间有程序替换了证书,常见于杀毒软件的 HTTPS 扫描或公司网络,关掉扫描或换网络;
  • pub get 成功但 IDE 仍标红:IDE 用的是另一份 Flutter SDK,在设置里把 Flutter SDK path 指向同一目录,然后重启 Dart 分析服务;
  • Could not resolve com.android.tools.build:gradle:Gradle 到不了 Google Maven,配置 gradle.properties 的代理或在 settings.gradle 里调整仓库顺序;
  • pod install 卡在 Analyzing dependencies:CocoaPods 的规格仓库下载慢,先执行 pod repo update,确认 cdn.cocoapods.org 能访问。

官方源、镜像与线路怎么选

镜像的好处是不需要代理,坏处是只管两段、可能滞后,而且 dart pub publish 不能走镜像。团队里有人发布自己的包,或者依赖刚发布的新版本,直连官方更省心。刺猬VPN支持按域名的智能分流,可以只让 pub.dev、storage.googleapis.com、dl.google.com 这几个域名走线路,国内服务照常直连。实际可用性取决于当前网络环境。

对比项会员节点直连官方社区镜像免费节点
包的新鲜度与 pub.dev 实时一致可能延迟数小时与官方一致
覆盖范围SDK、pub、Gradle 全部只覆盖 pub 与引擎产物全部,但负载不定
配置成本设一次代理变量设两个镜像变量同左
发布包dart pub publish 可用不支持发布可用
流量时长套餐有效期内不限流量、不限速由镜像决定永久免费、不限流量、不限速
适合场景日常开发与发布只需拉包且能接受延迟先判断是不是网络问题

Windows、macOS 与持续集成的差异

Windows 上最常见的坑是环境变量只设在当前 PowerShell 窗口里,换个窗口或在 Android Studio 里点运行就失效了。长期使用要在「系统属性」的「环境变量」里设置用户变量,并重启 IDE。路径里有中文或空格时,Gradle 偶尔会报奇怪的路径错误,把 Flutter SDK 放在 C:\src\flutter 这样的纯英文路径更稳。

macOS 上 Android Studio 从 Dock 启动时不会读取 ~/.zshrc,所以终端里能跑、IDE 里报 socket error。可以从终端用 open -a "Android Studio" 启动,让它继承终端的变量。持续集成机器没有图形界面,把代理或镜像变量写进流水线的环境配置,并缓存 ~/.pub-cache 与 ~/.gradle,第二次构建就不必重新下载。Linux 上用 snap 安装的 Flutter 有自己的沙箱,环境变量和缓存位置都与手动安装不同,遇到奇怪的权限或路径报错时,改用官方压缩包手动安装往往更省事。无论哪个系统,改完变量都要新开终端再验证,旧窗口里的变量不会自动刷新。

锁文件、缓存与团队协作

很多「别人能拉、我拉不下」的情况,其实不是网络问题,而是锁文件不一致。pubspec.lock 记录了每个依赖解析出来的确切版本,应用项目应当把它提交进仓库,这样所有人拉到的是同一组版本;插件或库项目则通常不提交,让使用者自己解析。如果同事改过依赖却没提交锁文件,你执行 pub get 时就会重新解析,可能解析到一个刚发布、镜像还没同步的版本,看起来就像下载失败。

缓存目录是全机共享的,同一台电脑上的多个项目会复用已经下载过的包。这意味着一旦某个包的归档下载到一半被中断,所有用到它的项目都会报同样的错,删项目里的 .dart_tool 文件夹没有用,要执行 dart pub cache repair 或者直接删掉缓存里那一个包的目录。缓存体积会随时间增长到几个 GB,执行 dart pub cache clean 可以整体清空,但下次每个项目都要重新下载,最好在线路稳定时再做。

团队里统一一份说明:Flutter 版本用哪个渠道、SDK 放在什么路径、代理或镜像变量怎么写、Gradle 的代理写在哪个文件。新成员第一次配置环境时,严格按说明顺序执行,每一步都看到成功提示再进入下一步。出现问题时,先报告终端停在哪一行、执行的是哪个命令,而不是笼统地说「依赖下载不了」,这样别人能直接判断是哪一段的问题。

Web、桌面端与版本切换带来的额外下载

只做手机端时,引擎产物下载一次就够了;一旦执行 flutter config --enable-web 或启用 Windows、macOS 桌面支持,下次构建时 Flutter 会再去下载对应平台的引擎产物,又会碰到一次 storage.googleapis.com。很多人以为环境早就配好了,结果第一次构建桌面版又卡住,原因就在这里。启用新平台后先执行一次 flutter precache --web 或对应参数,把产物提前拉好。

切换版本渠道也一样。执行 flutter channel beta 或 flutter upgrade 时,Flutter 会通过 Git 拉取新代码,再重新下载整套引擎产物,Git 那一段走的是 github.com,与 pub 的变量无关。用版本管理工具同时维护多个 Flutter 版本时,每个版本都有自己的 bin/cache,第一次切换到某个版本时都要完整下载一遍,所以不要在网络不稳的时候切换版本。升级失败时,先执行 git status 看 SDK 目录有没有被改过,被改动的文件会让升级中途停下。

迁移到新电脑时的顺序

  • 先装 Git 并确认能访问 github.com,再下载 Flutter SDK 压缩包或 clone 稳定渠道;
  • 把 SDK 的 bin 目录加入路径,新开终端执行 flutter --version,看到版本号再继续;
  • 设置代理或镜像变量,执行 flutter precache,让引擎产物一次下完;
  • 安装 Android SDK 并接受许可证,flutter doctor 的 Android 一项变成绿勾;
  • 最后进入项目执行 flutter pub get 与 flutter run,不要把旧电脑的缓存目录整个拷过来,版本不一致反而更难排查。

和其他开发下载工具的分工

Flutter 的 Android 端依赖完整的 Android SDK,sdkmanager 拉不下清单、许可证没接受、cmdline-tools 目录放错,这些与 pub 无关,处理方法见 Android SDK 下载失败排查。先让 flutter doctor 的 Android toolchain 变成绿勾,再处理 pub。

如果你同一台电脑上还要用 npm、pip、Docker,它们各有自己的镜像和代理变量,不要用 Flutter 的变量去修它们,统一的思路见 npm、pip、Docker 拉取失败排查。每个工具只改自己的配置,出问题时才能快速定位是哪一段。验收标准很简单:新开终端执行 flutter doctor 全部通过,pub get 与 flutter run 各成功一次。

常见报错速查表

现象原因解决办法
Got socket error trying to find package到不了 pub.dev确认 HTTPS_PROXY 在当前终端生效
Downloading Dart SDK 卡住引擎产物主机不通删 bin/cache 后 flutter precache
startup lock 等待旧进程未退出结束 dart 进程,删 lockfile
CERTIFICATE_VERIFY_FAILED证书被中间程序替换关闭 HTTPS 扫描或换网络
requires SDK version版本约束冲突改 pubspec 版本号
Could not resolve gradleGradle 不读代理变量在 gradle.properties 配代理
IDE 标红但命令行正常IDE 用了另一份 SDK统一 Flutter SDK path

高频问答

  • 问:设置了系统代理为什么 pub 还是超时?答:Dart 命令行读的是 HTTPS_PROXY 等环境变量,系统代理不一定生效,在终端里显式设置一次;
  • 问:镜像和代理能同时用吗?答:可以,但没必要,镜像变量会让 pub 绕开 pub.dev,出问题时更难判断是哪一边;
  • 问:flutter clean 能解决下载问题吗?答:不能,它只清项目构建产物,不碰 pub 缓存与引擎缓存;
  • 问:为什么第一次 flutter run 特别慢?答:首次要下载 Gradle 本体和全部 Android 依赖,几百 MB 很正常,之后会走本地缓存;
  • 问:能只给 Android Studio 走线路吗?答:客户端没有按应用勾选的功能,用按域名的智能分流覆盖相关下载域名即可;
  • 问:免费节点够用吗?答:够判断网络问题,首次拉全量依赖建议用时长套餐,有效期内不限流量、不限速。

把环境一次配稳

Flutter 与 pub.dev 依赖下载失败,拆开看是 SDK 产物、pub 包、Gradle 依赖三段各自的问题。先让浏览器能打开对应主机,再让终端变量生效,最后单独给 Gradle 配代理;每改一处就重跑一次对应命令,确认这一段通了再动下一段。团队文档里写清 SDK 路径、变量和缓存目录,新人照着做就不会重复踩坑。

刺猬VPN采用 HTTPS+AES 加密传输,自定义用户名和密码即可匿名注册,不需要邮箱和手机号;免费节点永久免费、不限流量、不限速;时长套餐有效期内不限流量、不限速,客户端支持按域名与 IP 的智能分流和断线保护,一个账号可在多台开发机上使用。依赖能否顺利下载取决于当前网络环境。

换刺猬VPN告别连接烦恼:一键连接、连接稳定

刺猬VPN提供永久免费节点,不限流量;无需邮箱,自定义用户名即可匿名注册。一个账号支持多设备同时在线,实际可用性取决于当前网络环境。