环境:Windows + 国内网络,Flutter 3.44.x / Gradle 8.10.2 / JDK 17。以下所有坑均在真实项目中反复踩过并验证过解法,纯干货,可直接抄作业。
如果你的 Flutter Android 构建出现以下任一症状,九成是锁文件问题:
validateSigningRelease 阶段莫名失败Could not add entry ... to cache xxx.bin不要 uninstall 重装、不要换 Flutter 版本、不要疯狂 clean——先把下面三层锁检查一遍。
位置:<flutter>/bin/cache/lockfile 和 <flutter>/bin/flutter.bat.lock
成因:任何 flutter / dart analyze 命令启动时都会创建这两个锁,正常退出会释放。但只要有一次异常退出(进程被杀、断电、构建中断),锁就残留。下次构建 flutter.bat 会卡在 acquire_lock 上无限等待——表现为 Gradle 日志停在某个 task 不动,dart.exe 进程根本没起来。
最阴险的地方:dart analyze 检查代码这种"人畜无害"的操作也会留锁。如果你构建前跑过分析命令,一定要清锁。
rm -f "<flutter>/bin/cache/lockfile" "<flutter>/bin/flutter.bat.lock"位置:C:\Users\<你>\.android\debug.keystore.lock
症状:整个构建一路绿灯,Kotlin 编译、AOT 编译、资源合并全部通过,最后倒在 :app:validateSigningRelease,报 AccessDeniedException。一小时白跑。
这个坑专挑 debug 签名的 release 构建下手,而且报错位置离真正的病灶(一个锁文件)十万八千里。解法很简单,构建前存在即删:
rm -f "C:/Users/<你>/.android/debug.keystore.lock"位置:<GRADLE_USER_HOME>/caches/<版本>/javaCompile/ 下的 classAnalysis.bin / jarAnalysis.bin
规律(重要):上一轮构建创建的缓存文件,到下一轮就变成"旧文件",写入时被文件系统拦截。表现为首轮构建成功、第二轮开始随机在 javaCompile 阶段报 Access Denied。这是渐进式的——GRADLE_USER_HOME 没有所谓的"永久健康"。
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 然后继续跑——这就是带病启动,必死。
正确的构建脚本(或 CI 流程)应该这样做:
① 删 <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 删除。