当iPhone进入待机模式时,iPhone应用程序会发生什么?

25
我的应用程序使用NSTimer,但似乎当iPhone进入待机模式时NSTimer不会触发(无论是通过按硬件按钮还是空闲计时器)。
当我再次激活iPhone时,我的应用程序仍然在前台。第三方应用程序在iPhone进入待机模式时会发生什么?
6个回答

46

虽然这里看不出来,但我相信原帖的作者通过在iPhone开发者论坛(此处提供)开启了一个线程找到了他问题的答案(我最终自己找到了这个线程,因为这里没有分享信息)。

如果其他人有同样的问题并在未来找到了这个页面,以下是“eskimo1”在苹果论坛上发表的有用回复(我稍微编辑了一下,以使其更易阅读而无需提供整个原始线程的上下文):

  • 关于iPhone应用程序状态术语,“active”并不意味着“唤醒”,而是指“附加到GUI”。 将其类比于Mac OS X中的“frontmost”。 当您锁定设备时,您的应用程序将停用,但设备可能会进入睡眠状态或不进入睡眠状态。
  • 如果设备连接到主电源(即通过USB),则iPhone OS很少处于睡眠状态。 但是,如果使用电池运行,则可能会进入睡眠状态。
  • 屏幕被锁定后不久(根据Oliver Drobnik的说法,为20秒),设备就会进入睡眠状态。 这就像关闭笔记本电脑的盖子一样,主CPU上的所有活动都会停止。
  • 如果设备在正确的音频会话中播放音频,则不会发生这种情况。 有关详细信息,请参见DTS Q&A QA1626“ Audio Session - Ensuring audio playback continues when screen is locked”
  • 请注意,idleTimerDisabled属性(可以打开以防止应用程序运行时屏幕关闭)是关于在用户不活动后锁定屏幕。 它与系统睡眠没有直接关系(间接相关,因为系统可能会在锁定后不久进入睡眠状态)。

谢谢克林特。我本来想在这里发布那个帖子的链接,但一直没来得及这样做。 - subjective-c
克林特,那很有用。谢谢! - Garth Kidd

14
请参阅iPhone OS编程指南中的“应用程序中断”部分,尤其是“applicationWillResignActive”和“applicationDidBecomeActive”事件。(整个指南都值得一读。)如果忽略这些事件,计时器似乎会继续运行一段时间,然后停止。听起来很合理,如果保持运行,应用程序可能很容易耗尽电池。那么应用程序到底发生了什么?我猜它根本没有获得任何CPU时间-它被冻结了,只有在您重新开机后才会解冻。

谢谢你的回答。iPhone编程指南的参考帮助我理解了正在发生的事情。 - subjective-c
我已经实现了这两种方法,但计时器仍然会在一段时间后停止。根据指南,应用程序仍在执行,但不会分派事件。有没有办法在应用程序处于挂起状态时保持计时器运行? - subjective-c
我猜它会将运行循环置于特殊模式。如果你能弄清楚这个模式是什么,那么你应该能够运行你的计时器。请注意,这只是一个猜测。 - Lily Ballard
根据指南,应用程序在挂起时不应执行任何操作。试图相反地做看起来是被拒绝的好方法。 - zoul
@zoul,按照我的理解,指南中说当应用处于挂起状态时,应该尽量减少电池的消耗而不是什么都不做。AppStore 中有些其他应用程序在 iPhone 锁屏后似乎仍在使用某种定时器。我只是不知道它们是怎么做到的。 - subjective-c

3

我的第一个建议是不要禁用空闲计时器,那只是一种hack。如果你想在UI事件期间保持计时器活动,请在当前运行循环上使用NSCommonModes运行计时器:

// create timer and add it to the current run loop using common modes

self.timer = [NSTimer timerWithTimeInterval:.1 target:self selector:@selector(handleTimer) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

1
你能再详细解释一下吗?NSCommonModes如何在设备休眠期间保持计时器的触发? - Carl Coryell-Martin
它不会在设备进入睡眠状态时保持运行,但会在 UI 事件期间保持运行。 - Amber Star

1

我在构建一个小样本时使用了这篇文章中的信息。这是我在启动播放以防止音频停止时使用的代码:

AudioSession.Category = AudioSessionCategory.MediaPlayback;

当应用程序完成播放后,要将其重置为原始值:

AudioSession.Category = AudioSessionCategory.SoloAmbientSound;

完整的示例在这里:

http://github.com/migueldeicaza/monotouch-samples/tree/master/StreamingAudio/


1
最近我在一个应用程序中遇到了这个问题,该应用程序使用了多个定时器和播放一些音频提示,我做了两个相对简单的更改:
AppDelegate中,我实现了以下方法,并且它们的存在允许应用程序在屏幕锁定时继续运行:
// this receives the notification when the device is locked
- (void)applicationWillResignActive:(UIApplication *)application
{ 
}

// this receives the notification that the application is about to become active again
- (void)applicationWillBecomeActive:(NSNotification *)aNotification
{
}

参考文献:UIApplicationDelegate协议参考NSApplication类参考在API文档(通过Xcode可访问,只需搜索applicationWillBecomeActive)。
我将主要的viewcontroller类作为一个AVAudioPlayerDelegate,并使用苹果公司“AddMusic”示例中的代码,使应用程序播放的音频警报与iPod音频等混合得很好。我只需要将这段代码放入一个在viewDidLoad期间调用的方法中即可。如果您对此感兴趣,则可以归入“应阅读本文档的人员类别”:音频会话编程指南
// Registers this class as the delegate of the audio session.
[[AVAudioSession sharedInstance] setDelegate: self];

// The AmbientSound category allows application audio to mix with Media Player
// audio. The category also indicates that application audio should stop playing 
// if the Ring/Siilent switch is set to "silent" or the screen locks.
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: nil];

// Activates the audio session.
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];

0

我相信你的应用程序在挂起时应该正常运行。(比如Pandora Radio)

检查一下你的计时器是否因为视图被隐藏或其他事件发生而被释放。


1
Pandora利用了几种声音播放模式之一,使其即使在屏幕锁定时仍能继续运行。 - mahboudz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接