假设你要开一家餐厅(编译 App):
AAPT2 = 你家餐厅的"头号大厨"
构建任务 = 客人点了一份"资源打包套餐"
Gradle = 餐厅经理,负责叫大厨干活
临时文件(.lock / .aapt2 文件夹)= 大厨的"围裙"和"菜板"

大厨有个脾气:他一旦开始切菜,就会把围裙挂在厨房门口,
上面写着"正在忙,别打扰"。这就是"锁文件"的作用 —— 防止别人同时进来捣乱。
【第一章:为什么会出现 AAPT2 问题】
某天正常营业:
经理(Gradle)喊:"大厨,来一份资源打包!"
大厨(AAPT2)麻溜地挂上围裙,开始切菜。
菜切完了,大厨收工回家。
一切正常。
但有一天出了意外 —— 客人突然取消订单,或者餐厅断电了(就是你编译到一半强行关闭终端)。
这个时候:
大厨还在厨房里切菜,突然"啪"一下停电了。
大厨立刻跑出厨房,但他的围裙还挂在门口!
菜板上还留着切到一半的菜叶子!
这就是所谓的"进程残留"和"锁文件损坏"。
第二天重新营业:
经理(Gradle)喊:"大厨,来干活了!"
大厨(AAPT2)走到厨房门口,看到围裙挂着。
大厨自言自语:"有人在里面?那我等等……"
等啊等,等到天黑都没人出来。
—— 因为你上次"啪"一下停电时,围裙没有被人摘下来。
大厨就这么卡在门口,永远不进厨房。这就是 Daemon startup failed。
【第二章:最终解决方案(叫醒大厨的正确姿势)】
这次做了五步,一步都不能少:
第1步:终止所有相关进程
-> taskkill /f /im java.exe(把厨房所有人赶出去)
-> taskkill /f /im javaw.exe
-> taskkill /f /im gradle.exe(把经理也赶出去)
第2步:删除 Gradle 守护进程
-> 删掉 ~/.gradle/daemon/*
-> 让经理彻底"失忆",下次重新从简历开始读
第3步:删除 Gradle 缓存锁文件
-> 删掉所有 *.lock 文件
-> 相当于把所有"正在忙"的牌子全部收走
第4步:删除 AAPT2 临时目录
-> 删掉 %TEMP%/.aapt2
-> 相当于把大厨的旧围裙、旧菜板全部扔掉,换新的
第5步:重新构建
-> ./gradlew :app:assembleDebug
-> 现在:
经理重启了,没有旧记忆
厨房干干净净,没有旧围裙
大厨高高兴兴走进厨房,挂上新围裙,开始切菜
BUILD SUCCESSFUL!大厨终于上班了!🎉
【总结一句话】
AAPT2 问题 = 大厨被旧围裙卡在厨房门口不肯干活。
彻底解决 = 赶走所有人 → 扔掉所有围裙和牌子 → 重新开业。
夜雨聆风