我在 Android 上播放 Ogg Vorbis 声音时遇到了一个奇怪的问题,我很难纠正。我正在使用 SoundPool 类来播放声音。除了暂停后播放的第一个声音外,它的效果很好。
这是我遇到的问题:我有一个菜单,上面有几个按钮。如果我按下按钮,我会播放滴答声。但是,我第一次尝试播放时,它不会发出声音。然后,如果我再次点击相同的菜单按钮,它就会起作用。如果我随后将下一次按下延迟几秒钟,则问题会再次出现。具体来说,我看到以下行为:
- 等待几秒钟
- 触摸应该发出声音的 UI 按钮......它没有
- 日志猫报告“AudioFlinger:写入阻塞 165 毫秒,66 次延迟写入,线程 0xec40”(当我触摸 UI 按钮时立即发生)
- 等待几秒钟
- 日志猫报告“AudioHardwareQSD:AudioHardware pcm 播放将进入待机状态”
- 触摸应该发出声音的 UI 按钮......它没有。
- logcat 报告“AudioFlinger:写入阻塞 166 毫秒,67 延迟写入,线程 0xec40”(当我触摸 UI 按钮时立即发生)
- 再次触摸 UI 按钮,但在AudioHardwareQSD 待机消息出现之前...声音工作!
我在几个不同的设备上看到了这种行为:HTC Incredible、rooted Nook Color 和 HTC Thunderbolt,所以我不相信它是特定于设备的。
我猜这是 AudioHardwareQSD 进入待机状态的功能。一旦它处于待机状态,从滑槽发出的第一个声音就会被忽略,而随后的声音会继续工作,直到它再次进入待机状态。我的 HTC Incredible 上的“写被阻止”消息和 AudioHardwareQSD 消息之间大约有 3 秒的延迟。
这里有一个关于 StackOverflow 的答案,讨论了使用 WakeLock 来防止这种情况发生。我尝试了该解决方案,但并没有解决我的问题。
为什么会这样?有没有办法防止 AudioHardwareQSD 进入待机状态?有人对解决此问题有任何提示吗?
谢谢!
更新:我已经能够实施一个相当粗糙的解决方法来纠正这个问题。在我的应用程序(游戏)中,我有一个更健全的渲染类。我添加了一个由游戏逻辑定期执行的新方法 present()。该方法使用 1.5s 超时计时器。当计时器触底时,声音渲染器会播放一个包含 50 毫秒静音的音频文件,然后重置计时器。
这已经纠正了我的问题......远非最佳,但它有效。