IOS工程:NSThread sleepForTimeInterval的使用,游戏中途中断(接电话或者点击Home按钮),重新回到游戏音频音效失效问题
设备/引擎:Mac(11.7)/cocos
开发工具:Xcode
开发语言:c++/java
错误信息:AVAudioSession_iOS.mm:1271 Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.
最近工程中用户反馈游戏在中途被中断再回来会出现所有音效消失的情况,体验上会不太好,一开始考虑是可能在哪里不小心设置了stopEffect的选项,查了一圈并没有,所以就打断点来测试,发现有个报错信息如下:AVAudioSession_iOS.mm:1271 Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.
乍一看可以判断是音频冲突的问题,用Chatgpt查了一下,给出了检查是否在恢复音频时已经有其他音频流在运行,以及可以增加延迟来避免这种情况,如下图:
通过提示也基本有了修改的思路,之前工程中的源码是直接调用恢复音频的代码,这块的隐患在于视觉上是直接调用执行的,但在程序运行时,方法调用及执行会有所延迟,当运行恢复音频的代码时,可能程序中已经有其他的功能开始运行了,也就有可能会出现音频流冲突的问题。所以修改的方法便是去延迟调用相关的恢复音频的代码。
如下图是开始时的代码:
void AppDelegate::applicationWillEnterForeground()
{
SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
SimpleAudioEngine::sharedEngine()->resumeAllEffects();
CCDirector::sharedDirector()->startAnimation();
}
如下是修改后的代码,在.mm文件中进行延迟:
void AppDelegate::applicationWillEnterForeground()
{
DeviceManager::sharedManager()->resumeAllSounds();
CCDirector::sharedDirector()->startAnimation();
}
.mm文件修改如下:
void DeviceManager::resumeAllSounds()
{
dispatch_queue_t resumeQueue = dispatch_queue_create("resumeSound", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(resumeQueue, ^{
CCLog("check resume");
[NSThread sleepForTimeInterval:0.5];
CocosDenshion::SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
CocosDenshion::SimpleAudioEngine::sharedEngine()->resumeAllEffects();
});
}
以上为新添加的一个异步执行的代码块,用来添加延迟调用的效果,并保证在程序恢复前都被执行完成。避免程序多任务间的冲突问题。NSThread sleepForTimeInterval:0.5
函数就是延迟操作的代码。
至此就将音频无响应的问题解决了。
希望能给大家带来帮助!!!有什么问题需要讨论的可以评论私信欢迎讨论~