资讯动态

Flutter Android构建卡住?从Gradle到依赖缓存的全链路排查指南

发布时间:2026/10/18 15:19:06 来源:尧图企业网站定制
我们排查 Flutter Android 项目卡住的那些瞬间其实大多不是玄学而是构建链路某个环节停住了。这篇文章我会按自己真实的排障习惯一条一条带你看。1. 先分清“这一步”卡在哪构建进程不同排查方向完全不同1.1 终端里停留的最后一句话就是最好的线索很多人在开发者社区提问时标题只会写“到这一步就卡住了”。“这一步”到底是哪一步截图里往往就一行字比如Running Gradle task assembleDebug...或者是Waiting for another flutter command to release the startup lock又或者是连错误都没有的空白光标。面对这些情况我最早犯过的错是看到“卡住”就到处搜教程东改一处西换一个版本折腾一晚上还是没解决。后来我养成了一个习惯不把“卡住”当整体现象而是先看终端里最后停下的那一条提示然后问自己三个问题这行提示是 Flutter 命令输出的还是 Gradle 输出的它发生后CPU 和网络还有没有动静之前一次能正常跑通时走到这一步大概花了多久把这三个问题回答清楚再去查资料效率会高很多。1.2 Flutter Android 从 Run 到上屏要走完哪六段路Flutter 项目在 Android 上启动并不是只靠 Dart 代码直接变成 APK。你点击 Run 之后实际会经历六个阶段pub get解析 pubspec.yaml 里的依赖并把依赖包拉到本地缓存。调起 Gradle Wrapper让 Gradle 引擎读取 android 目录下的构建脚本。Gradle 解析并下载 Android 构建所需依赖包括 Android Gradle Plugin、Kotlin 相关库、第三方插件等。执行assembleDebug打包 APK。通过 adb 把 APK 安装到连接的设备或模拟器。安装完成后启动应用随后 Flutter 引擎 attach 到调试器。这六步每一步都可能卡住但屏幕上都只显示一个类似“正在构建”的状态。如果不先定位到具体阶段很容易把所有问题混在一起乱猜。比如有人flutter run卡住就去改 Gradle 镜像结果问题其实出在 adb 没有识别到设备白白耽误半天。1.3 真卡死与假缓慢的区分方法判断是慢还是卡我通常会同时看三个信源终端的输出频率、任务管理器的 CPU 占用、网络或磁盘的活动状态。如果终端在几分钟内持续滚动新日志而且 CPU 占用率一直有波动那多半是还在干活只是速度慢。这时候你不需要慌张可以泡杯茶再等几分钟。如果最后一行已经停留了十几分钟CPU 几乎归零网络也没有下载流量那才是真卡死了。还有一类“假卡”flutter run停在询问是否允许网络、或者 Android Studio 弹了某个授权窗口但你切到了别的窗口没看到。这种情况最搞笑也最容易忽略。遇到卡住时先切到 IDE 主窗口和系统通知栏看一看也许不是进程死了只是它在等一个永远不会被点击的对话框。2. 最常见的卡死源头Gradle 发行包与依赖仓库2.1 一个 Flutter 项目为什么会卡在 Gradle 层很多新手会问我写的明明是 Dart 代码为什么构建时要下载 Gradle原因是 Flutter 的 Android 工程本质上仍然是一个 Android 工程它使用 Gradle 作为构建工具。Gradle 负责把 Android 资源、Java/Kotlin 代码、Manifest 配置、依赖库整合起来最终生成 APK。Gradle 本身就好比一个建筑队的小头目它要指挥各种材料到位。但它第一件事并不是盖楼而是先确认自己这个版本的工具包是否已经在本地。android/gradle/wrapper/gradle-wrapper.properties文件里写着 Gradle 的发行版下载地址。如果本地缓存里没有这个版本Gradle Wrapper 会先下载一个压缩包这个压缩包通常几十上百 MB下载速度一旦被网络拖累就会长时间停在那里。于是你看到的Running Gradle task assembleDebug...其实是在下载 Gradle 本身而不是在编译代码。2.2 三个文件定位 Gradle 下载卡点要确认是不是 Gradle 下载的问题我一般会先看三个地方android/gradle/wrapper/gradle-wrapper.properties看distributionUrl指向哪个域名对应哪个版本号。本地~/.gradle/wrapper/dists/目录查看对应版本目录下有没有.part或.lck文件有就说明下载未完成。android/settings.gradle或android/build.gradle看仓库源的配置顺序依赖解析是从这些仓库里拉取。拿我自己的经验来说卡在这种地方时任务管理器里往往有网络流量但非常零星速度长期徘徊在几 KB/s 到几十 KB/s。如果你看到的正是这个状态不用怀疑多半是网络到默认下载域名的链路太挤了。2.3 给发行包和依赖仓库“体检”和换源搞清楚是下载问题之后剩下就是换源和预下载两条路线。换源时要改的是gradle-wrapper.properties里的distributionUrl把原来的官方下载地址替换成能更快访问的公共镜像地址。改的时候注意版本号不能随意动还是保持原文件里写的版本只换域名部分最稳妥。改完拿新的 URL 在浏览器里试着下载一次确认能被完整拉下来再重新跑构建。依赖仓库的配置也类似。很多项目会同时依赖 Google Maven 仓库和 Maven Central 仓库这两个是下载依赖库的主要来源。如果卡在某个 Could not resolve或 IDLE状态可以在仓库列表最前面插入镜像源。但要记住一个原则不能把它放在最前面就顺手把原始仓库删了因为有些冷门插件只发布在官方指定仓库全删之后反而会报依赖找不到。2.4 修改源之后必须处理的残留缓存换完源还有一个新手特别容易踩的细节旧缓存没清理。比如 Gradle 已经下载了一半的.part文件或者下载完整但被标记成坏文件的目录都会导致重新构建时仍然卡住。正确的做法是把~/.gradle/wrapper/dists/下对应版本号的目录先改个名字备份确认新下载能用再删除依赖仓库缓存同样可以清理~/.gradle/caches/但这一步改动影响较大建议优先只处理 wrapper。清理完之后先跑一次./gradlew --stop把之前可能残留的 Gradle 守护进程全部停掉再重新flutter run。这一步经常被忽略但很实用能避免守护进程里保存的旧状态继续干扰。3. Flutter 与 Android 工具链不咬合也会假死3.1 第一次 flutter run 时的 Engine artifacts 下载Gradle 下载解决之后还有一类卡住发生在 Flutter 工具链自身。首次跑flutter run时Flutter 会按目标平台下载对应的 Engine artifacts包括编译好的 Flutter engine、sky_engine 相关文件、字体和 shader 等。这些文件默认放在 Flutter SDK 的bin/cache或用户级缓存目录里。刚才那种“等了很久都没反应”有可能最后一行是类似Downloading...的字样但前面没有显示进度百分比。这种情况我也遇到过嘴上说“卡住了”其实是在大包下载。处理办法通常不是等而是检查 Flutter SDK 的缓存目录确认文件大小是不是在增长。如果确实在增长就耐心等如果完全不动可能是下载源不通需要看flutter config --list是否设置了镜像或者手动把缓存目录中的临时文件清掉重新下载。3.2 JDK 版本和 Android Gradle Plugin 需要配对另一个容易被忽视的卡点是 Java 环境与 Android Gradle Plugin 版本不匹配。Flutter 的 Android 构建依赖 JDK但不同版本的 Android Gradle Plugin 对 JDK 版本要求不一样。JDK 太老或太新构建过程会在某个没有报错信息的地方僵住或者输出一堆让新手害怕但实际只因版本不对的异常。检查方式很简单终端跑flutter doctor -v看 Java 版本再打开android/settings.gradle里的plugins块确认 Android Gradle Plugin 和 Kotlin 版本。各版本对 JDK 的要求并不复杂但如果你之前自己手动装过多个 JDK很容易出现 IDE 里配置的是 JDK 17命令行里却指向 JDK 8构建时卡得不明不白。这时候就需要统一环境变量JAVA_HOME保证 IDE 和命令行用的是同一个 JDK。3.3 插件版本互相打架时的表现与排查还有一类卡住既不是网络问题也不是工具链版本问题而是依赖插件冲突。具体表现是 Gradle 构建阶段输出大量日志但最后走到某个 Task 时突然停住或者 sync 时一直转圈不结束。这种我来按一个“最小化排除法”处理先把pubspec.yaml里的第三方依赖注释掉只保留项目自带的那几个基础包运行一次。如果构建能走通就一个一个把插件加回来每次只加一个并跑一次构建很快就能定位到是哪个插件把构建卡住。定位到之后查看它的 Android 配置要求把相关 SDK 版本、依赖版本对齐即可。4. 三种能帮你“看到卡点”的透视手段4.1 flutter run --verbose 读尾行默认的flutter run输出比较精简很多中间细节被隐藏了。遇到疑难卡死我会先跑一次带 verbose 的启动命令比如flutter run --verbose。它会输出比平时多得多的时间线要点不是看全部而是看最后那几行。举个例子如果最后一行显示正在执行:app:processDebugMainManifest卡点就在清单合并阶段如果显示:app:mergeDebugNativeLibs则多半和 so 库、NDK 有关。有了这一步的小标记再去搜对应的 Gradle Task 名能少走很多弯路。4.2 绕过 Flutter 直接跑 Gradle第二个更直接的透视手段是绕过 Flutter直接进 android 目录跑 Gradle。在 Android Studio 的 terminal 里执行cd android然后./gradlew assembleDebug --stacktrace。这么做的好处是把现场从 Flutter 的整体流程里剥出来单独验证 Gradle 本身能不能完成构建。我自己就试过一种情况Flutter CLI 卡在Running Gradle task...但直接用 Gradle 命令跑时几秒钟就失败了并给出具体异常。原来问题根本不在网络而在某个依赖坐标格式写错Flutter 层面吞掉了详细报错。所以在排查时分两步走很有意义先用 Flutter 命令看表现再用 Gradle 命令拿细节。4.3 adb devices、系统监视器与磁盘空间第三个手段比较朴素却是很多人忘掉的确认手机/模拟器状态和系统资源。每次flutter run前我都先执行一次adb devices确认设备编号后面跟着的是device而不是unauthorized。如果状态是unauthorized需要在手机上点“允许调试”否则 Flutter 会一直等待设备授权而看起来像卡住。与此同时打开系统监视器看磁盘占用。Android 构建过程中会生成多个临时文件磁盘如果剩下不到几个 GB构建可能在某一步停住表现得和“卡死”一模一样。5. 照着做也踩过的坑与快速自救清单5.1 无脑删除 build 目录的代价遇到构建卡住很多人的第一反应是把android和根目录下的build目录删掉以为这样可以来个“干净重来”。我当初也这么干过结果不仅没有加速反而让下一次构建从头开始把之前好不容易缓存的增量编译全部扔掉了构建时间变得更长。正确做法是有条件地清理只想清理编译碎片时用flutter clean就足够想连 Gradle 缓存一起处理时再配合./gradlew clean。千万不要每次卡住就删build尤其不要在项目依赖较多的情况下去删除非你已经确认缓存文件损坏否则这纯粹是添乱。5.2 “全部升级到最新版”并不总能解决问题还有一类陷阱来自“升级依赖能解决一切”的想法。我见过有朋友为了处理构建卡顿把 Flutter SDK、Android Gradle Plugin、Kotlin 版本全部升到最新结果卡得更厉害。原因是 Flutter 版本和 Android Gradle Plugin 之间存在理性的兼容窗口新版本 Flutter 往往要求特定范围的 AGP并不是越新越好。我的原则是能用锁定版本的不轻易动版本实在需要升级的一次只升一个。验证完再动下一个可以避免把多变量的兼容问题搅成一团乱麻。5.3 可以固化的快速自查清单最后把这些经验浓缩成一张速查清单我每次遇到“flutter Android 项目卡住”都会按顺序过一遍阶段检查项卡住时的常见表现处理建议依赖解析pubspec.yaml 里的插件版本pub get长时间不动查看 pub 缓存目录确认是否在下载Gradle 发行包gradle-wrapper.properties 里的 distributionUrl卡在 Gradle task网络流量极小换成可快速访问的镜像清理.part缓存依赖仓库settings.gradle 中 repositories 顺序停在某个依赖解析任务镜子源前置但保留原仓库兜底JVM/Gradle 环境java -version与 AGP 的兼容性构建中途无报错停住统一 JDK 版本查看 AGP 兼容表设备连接adb devices输出flutter run 等待设备查看是否 authorized检查 USB 调试授权磁盘空间系统磁盘剩余空间构建写到临时文件时卡住清理磁盘保留足够空间缓存损坏本地 Gradle/Flutter 缓存反复卡在同一位置flutter clean和./gradlew --stop后重试其实每次把以上这些过一遍之后很大概率能找到卡住的原因。之前我有过一次比较典型的经历项目整整卡在Running Gradle task...两个小时最后发现只是gradle-wrapper.properties里的发行包域名连接不通。改掉那一行整个构建恢复正常。从那以后我就更坚定地认为所谓“大神一眼看出问题”在他们眼里从来就没有玄学只有步骤和证据。你只要愿意把问题拆细一点多保留几行日志距离解决方法就不远了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑