我的 Android 应用程序(minSdkLevel: 2.2, targetSdkLevel: 3.0, testing on Nexus 7 with Android 4.2)在加载阶段执行以下操作:
- 创建一个并在其上
SoundPool
注册一个OnLoadCompleteListener
- 开始加载声音。
SoundPool
每当加载声音时调用我的回调方法。 - 如果加载过程被用户中断,
SoundPool.release()
则调用 - (如果
release()
已经调用并且之前开始的声音加载完成,即系统调用我的回调,那么我的应用程序检测到我SoundPool
的已经是null
并忽略回调,所以它是安全的)。
在 Nexus 7 上进行测试,调用后 210 毫秒出现以下错误SoundPool.release()
(logcat):
即事件顺序可能如下:
- 由于我的
SoundPool.load(...)
调用,系统开始异步加载声音 - 我离开了加载屏幕,所以
SoundPool.release()
被调用并SoundPool
设置为null
- (?) 系统完成了较早的声音加载完成回调,但遇到了一些错误。
我检查了 Android 源代码和 JNI 代码SoundPool.release()
确实删除了SoundPool
JNI 中的DeleteGlobalRef
. 它使用弱引用来存储SoundPool
Java 级别的引用。
我无法重现该错误,可能是因为由于不确定性,我无法重现确切的条件。系统应该正确处理SoundPool
异步加载声音时可能会释放的问题,但似乎在极少数情况下会出现错误。(请注意,我的代码SoundPool
在 nullcheck 后仅发布一次,因此该错误肯定不在我的代码中)。
关于为什么在Android中会发生这样的错误的任何想法?从理论上讲,我的上述怀疑是否正确?如何保护我的应用程序免受这个 Android 错误的影响?也许我可以尝试设置一个SoundPool
应该被释放的布尔值,等到所有回调返回,然后在最后一个回调中释放它(基于这个布尔值)?我想不出任何其他解决方法,但我想确保它至少会起作用。