SoundPool 异步加载释放竞态修复变更记录

日期:2026-07-31

变更结论

已完成应用侧修复:语音加载、加载完成后的播放以及页面生命周期释放现在通过同一资源门禁串行协调。页面先释放 SoundPool 后,晚到的异步加载回调会被忽略,不再访问已经置空或释放的 SoundPool。

崩溃特征与根因

java.lang.NullPointerException: Attempt to invoke virtual method
'int android.media.SoundPool.play(...)' on a null object reference
at com.cpt.zhct.weighting.utils.SoundPoolPlayer.play(SoundPoolPlayer.java:82)
at com.cpt.zhct.weighting.utils.SoundPoolPlayer$1.onLoadComplete(SoundPoolPlayer.java:66)

根因是 SoundPool.load() 异步执行。语音尚未加载完成时,Activity 或 Fragment 的 onStop() 可能先调用 release(),随后加载完成回调仍调用 play(),形成释放后访问竞态。

项目文件变更

修改

新增

测试驱动验证

回归测试先在资源门禁尚未实现时按预期编译失败;完成最小实现后,定向测试返回 BUILD SUCCESSFUL in 6s

全量测试与构建

./gradlew testDebugUnitTest assembleDebug --console=plain

使用 JDK 8 执行,结果为 BUILD SUCCESSFUL in 34s

风险与待验收

Git 状态

当前分支为 fun_tray_recognition_control。本次未执行暂存、提交、推送或分支切换;工作区原有硬件管理、红外弹框布局、相关测试和 output/ 内容未纳入本次改动。