首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Flutter Android 构建避坑实录(一):三层锁文件陷阱,每一层都能让你白跑一小时

Flutter Android 构建避坑实录(一):三层锁文件陷阱,每一层都能让你白跑一小时

原创
作者头像
用户12714909
发布2026-08-25 18:44:39
发布2026-08-25 18:44:39
250
举报

环境:Windows + 国内网络,Flutter 3.44.x / Gradle 8.10.2 / JDK 17。以下所有坑均在真实项目中反复踩过并验证过解法,纯干货,可直接抄作业。

先说结论

如果你的 Flutter Android 构建出现以下任一症状,九成是锁文件问题:

  • 构建启动后长时间无输出,最后"拒绝访问"(Access Denied)
  • validateSigningRelease 阶段莫名失败
  • Could not add entry ... to cache xxx.bin
  • Gradle 卡在某个阶段 1 小时以上零产物
  • 昨天还能构建,今天一模一样的代码突然不行了

不要 uninstall 重装、不要换 Flutter 版本、不要疯狂 clean——先把下面三层锁检查一遍。

第一层:Flutter SDK 自己的锁

位置<flutter>/bin/cache/lockfile<flutter>/bin/flutter.bat.lock

成因:任何 flutter / dart analyze 命令启动时都会创建这两个锁,正常退出会释放。但只要有一次异常退出(进程被杀、断电、构建中断),锁就残留。下次构建 flutter.bat 会卡在 acquire_lock 上无限等待——表现为 Gradle 日志停在某个 task 不动,dart.exe 进程根本没起来。

最阴险的地方dart analyze 检查代码这种"人畜无害"的操作也会留锁。如果你构建前跑过分析命令,一定要清锁。

代码语言:bash
复制
rm -f "<flutter>/bin/cache/lockfile" "<flutter>/bin/flutter.bat.lock"

第二层:签名锁 debug.keystore.lock

位置C:\Users\<你>\.android\debug.keystore.lock

症状:整个构建一路绿灯,Kotlin 编译、AOT 编译、资源合并全部通过,最后倒在 :app:validateSigningRelease,报 AccessDeniedException一小时白跑

这个坑专挑 debug 签名的 release 构建下手,而且报错位置离真正的病灶(一个锁文件)十万八千里。解法很简单,构建前存在即删:

代码语言:bash
复制
rm -f "C:/Users/<你>/.android/debug.keystore.lock"

第三层:Gradle 缓存的"渐进式污染"

位置<GRADLE_USER_HOME>/caches/<版本>/javaCompile/ 下的 classAnalysis.bin / jarAnalysis.bin

规律(重要):上一轮构建创建的缓存文件,到下一轮就变成"旧文件",写入时被文件系统拦截。表现为首轮构建成功、第二轮开始随机在 javaCompile 阶段报 Access Denied。这是渐进式的——GRADLE_USER_HOME 没有所谓的"永久健康"。

代码语言:bash
复制
rm -rf "<GRADLE_USER_HOME>/caches/8.10.2/javaCompile"

Gradle 会自动重建这些缓存,删了不心疼。凡是看到 Could not add entry ... to cache xxx.bin,就是这病。

顺带一提:为什么删个文件这么难?

Windows 下文件删除有个隐藏坑:如果删除操作被安全机制转交给回收站工具,而那个工具的可执行文件路径里含空格,调用会直接超时失败。实测各删除通道能力差异巨大:

通道

删新建文件

删旧文件/锁文件

程序内 fs.unlinkSync

程序内 cmd /c del

程序内 bash rm

独立的 shell 通道(管理员级)

✅ 唯一可靠

所以如果你的构建脚本是"程序内自己删锁",删失败只是打个 warning 然后继续跑——这就是带病启动,必死

铁律:锁删除失败 = FATAL

正确的构建脚本(或 CI 流程)应该这样做:

  1. 启动前检查所有锁文件,删除失败立即退出,绝不带病启动
  2. 检查无 java/dart/cmd 孤儿进程残留
  3. 启动后看前 2 分钟日志,确认真正进入编译阶段

启动前检查清单(按序执行)

代码语言:txt
复制
① 删 <flutter>/bin/cache/lockfile + flutter.bat.lock
② 删 C:/Users/<你>/.android/debug.keystore.lock(存在即删)
③ 删 <GRADLE_USER_HOME>/caches/<ver>/javaCompile(上一轮跑过就删)
④ tasklist 确认无 java/gradle/dart 残留进程
⑤ 全过 → 启动,盯前 2 分钟日志

按这个清单走,我这边实测构建从"随机失败 + 动辄一小时僵死"变成了稳定 15 分钟出包。下一篇讲怎么判断构建是真干活还是已经僵死——这里面的坑更深。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 先说结论
  • 第一层:Flutter SDK 自己的锁
  • 第二层:签名锁 debug.keystore.lock
  • 第三层:Gradle 缓存的"渐进式污染"
  • 顺带一提:为什么删个文件这么难?
  • 铁律:锁删除失败 = FATAL
  • 启动前检查清单(按序执行)
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档