当一个应用程序从后台被唤醒,你想让它准备为活动时,哪个是正确的委托来实现?

applicationwillenter前台vs applicationDidBecomeActive——有什么区别?

当应用程序将进入睡眠状态,你想让它准备清理和保存数据时,应该实现哪个委托呢?

applicationWillResignActive vs. applicationDidEnterBackground—有什么区别?

此外,我还注意到当传入短信或电话进来时,applicationWillResignActive被调用,但用户选择单击Ok并继续。我不希望我的应用程序在这些情况下采取任何行动。我只是想让它继续运行,没有任何中间清理,因为用户没有退出应用程序。所以,我认为它更有意义,只在applicationDidEnterBackground做清理工作。

我希望您能提供一些最佳实践,帮助我们选择使用哪些委托来唤醒和入睡,以及考虑像被短信/电话打断这样的事件。

谢谢


当前回答

在iOS 8+中,接听电话有一个微妙但重要的区别。

在ios7中,如果用户接听电话,会同时调用applicationWillResignActive:和applicationDidEnterBackground:。但是在iOS 8+中只有applicationWillResignActive:被调用。

其他回答

applicationwillenter前台被称为:

当应用程序重新启动(从后台到前台) 当应用程序第一次启动时,即当applicationDidFinishLaunch被调用时,该方法不会被调用,而只在来自后台时调用 applicationDidBecomeActive

applicationDidBecomeActive被调用

当应用程序在didFinishLaunching后第一次启动时 在applicationwillenter前台之后,如果没有URL要处理。 调用handleOpenURL。 在applicationWillResignActive后,如果用户忽略中断,如电话或短信。 在alertView从应用程序的任何地方消失后

管理应用的生命周期有助于解决你的问题。对于快速概念,您可以查看该文档中的图。 你也可以从XCode向导生成的代码中读取注释。列出如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    /*
     Sent when the application is about to move from active to inactive state. 
     This can occur for certain types of temporary interruptions (such as an 
     incoming phone call or SMS message) or when the user quits the application 
     and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down 
     OpenGL ES frame rates. Games should use this method to pause the game.
     */
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    /*
     Use this method to release shared resources, save user data, invalidate 
     timers, and store enough application state information to restore your 
     application to its current state in case it is terminated later. 
     If your application supports background execution, this method is called 
     instead of applicationWillTerminate: when the user quits.
     */
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /*
     Called as part of the transition from the background to the active state; 
     here you can undo many of the changes made on entering the background.
     */
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the 
     application was inactive. If the application was previously in the 
     background, optionally refresh the user interface.
     */
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    /*
     Called when the application is about to terminate.
     Save data if appropriate.
     See also applicationDidEnterBackground:.
     */
}

更详细的解释请参考UIApplicationDelegate的官方文档

当唤醒,即重新启动一个应用程序(通过跳板,应用程序切换或URL) applicationwillenter前台:被调用。它只在应用准备好使用时执行一次,在被放入后台后,而applicationDidBecomeActive:可能在启动后被调用多次。这使得applicationWillEnterForeground:非常适合重新启动后只需要发生一次的设置。

applicationwillenter前台:被称为:

当应用程序重新启动 applicationDidBecomeActive之前:

applicationDidBecomeActive:被调用:

当应用程序第一次启动后应用程序:didFinishLaunchingWithOptions: after applicationwillenter前台:如果没有URL要处理。 调用handleOpenURL。 after applicationWillResignActive:如果用户忽略中断,如电话或短信。

applicationWillResignActive:被调用:

当有电话之类的干扰时。 如果用户进行呼叫,则调用applicationDidEnterBackground。 如果用户忽略调用,则调用applicationDidBecomeActive。 当用户按下home键或切换应用程序时。 医生说你应该 暂停正在进行的任务 关闭定时器 暂停游戏 降低OpenGL帧速率

applicationDidEnterBackground:被调用:

applicationWillResignActive之后: 医生说你应该: 释放共享资源 保存用户数据 无效计时器 保存应用程序状态,以便在应用程序终止时恢复它。 禁用UI更新 您有5秒钟的时间来做需要做的事情并返回方法 如果你在5秒内没有返回,应用将被终止。 你可以用beginBackgroundTaskWithExpirationHandler请求更多的时间:

官方文件。

我对达诺的回答还是有点困惑,所以我做了一个小测试,以获得某些场景下的事件流,供我参考,但它可能对你也有用。这是针对那些在info.plist中没有使用UIApplicationExitsOnSuspend的应用程序。这是在iOS 8模拟器上进行的,并与iOS 7设备进行了验证。请原谅Xamarin的事件处理程序名称。它们非常相似。

从非运行状态初始启动和所有后续启动:

FinishedLaunching OnActivated

打断(电话,上滑下滑,下滑上滑) Home键双击列出不活跃的应用程序,然后重新选择我们的应用程序:

OnResignActivation OnActivated

Home键双击列出非活动应用程序,选择另一个应用程序,然后重新启动我们的应用程序: 单按Home键,然后重新启动: 锁定(开/关按钮),然后解锁:

OnResignActivation DidEnterBackground WillEnterForeground OnActivated

双击Home键,并终止我们的应用程序:(随后重新启动是第一种情况)

OnResignActivation DidEnterBackground DidEnterBackground(仅限iOS 7 ?)

是的,DidEnterBackground在iOS7设备上被调用了两次。两次UIApplication的状态都是Background。但是,iOS 8模拟器没有。这需要在iOS 8设备上进行测试。我拿到答案后会更新的,或者其他人可以确认。

在iOS 8+中,接听电话有一个微妙但重要的区别。

在ios7中,如果用户接听电话,会同时调用applicationWillResignActive:和applicationDidEnterBackground:。但是在iOS 8+中只有applicationWillResignActive:被调用。