我在商店里有一个音频应用程序。它适用于 iOS 4.0 之前的 iPhone OS 版本。我正在开发一个新版本,首先让应用程序符合新的 iOS 多任务处理功能。(我的 iPhone 上装有 iOS 4.0,并已升级到最新的 xCode 和 SDK。)
结果是一场演出。
o 当我在 iPhone 上安装应用程序并在调试器中运行时,或在 iPhone 关机后启动应用程序时,应用程序运行良好 - 当我按下按钮时播放音频,或从保存的“状态”重新启动音频上次运行应用程序的时间。
o 如果我尝试按下 Home 按钮,然后从后台重新启动应用程序,音频(a 和 1-n 音频流的混合)会发出只有我能识别的断断续续的声音。
o 如果 - 在音频清晰的情况下 - 我拨打 iPhone,我可以接听或拒绝接听电话。在这两种情况下,应用程序都会干净利落地恢复正常运行。
请注意,在后台模式下我不会尝试播放任何内容。我只是想关闭一些东西并在被问到时将它们带回来。
技术:所有的音频逻辑都使用 RemoteIO。(我计划有一天做一些相当复杂的信号处理。)
请原谅伪代码叙述 - 一些真实代码非常广泛。
主视图控制器:
o viewDidLoad - 没什么特别的
o didBecomeActive 将自己设置为音频会话委托;将 AudioSessionCategory 设置为 MediaPlayback;设置 AudioSessionActive;创建一个播放器(见下文);重新启动之前播放的任何声音;
o willResignActive 保存正在播放的状态;停止所有声音;停止播放器;将音频会话设置为非活动状态;
o didEnterBackground - 什么都没有(方法已注册,但没有内容。)
o willEnterForeground - 什么都没有(方法已注册,但没有内容。)
Player 概述 - 我的班级:Player 是一个单身人士。我确保单例实例被销毁,并在 didBecomeActive 中创建了一个新实例。实例化单例实际上会启动 AudioUnit。
构造函数setupRemoteIO;启动音频输出单元开始;停止音频输出单元停止;播放器回调通常的东西;
>
以下是我的 MainViewController 中的一些方法:
(void)willResignActive:(NSNotification *)note {
[ self saveState ];
[ [ NaturePlayer getInstance ] stopAllSounds ];
[ [ NaturePlayer getInstance ] stop ];
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: NO error: &activationError];
[NaturePlayer destroy];
}
- (void)didBecomeActive:(NSNotification *)note {
[ self setupAudioSession ];
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
[ self restartSounds ];
[ self setViewState ];
}
- (void)didEnterBackground:(NSNotification *)note {
int xxx = 1;
}
- (void)willEnterForeground:(NSNotification *)note {
int xxx = 1;
}
- (void) applicationWillTerminate: (NSNotification*) notification {
int xxx = 1;
}
这是 NaturePlayer 的一个方法:
/**
* Stop the playback process.
*/
void NaturePlayerDelegate::stop() {
if (isPlaying_) {
AudioOutputUnitStop(outputUnit_);
isPlaying_ = FALSE ;
}
}
我检查了:正在调用 stop(),然后调用 AudioOutputUnitStop(); 还检查了:AudioOutputUnitStop 上的文档说它会阻塞,直到所有活动完成。