applicationWillEnterForeground与applicationDidBecomeActive,applicationWillResignActive与applicationDidEnterBackground

问题描述 投票:196回答:6

当应用程序从后台唤醒并且您希望它准备好处于活动状态时,哪个是正确的代理?

applicationWillEnterForeground vs applicationDidBecomeActive - 有什么区别?

当应用程序进入休眠状态并且您想要准备它以清理和保存数据时,哪个是适当的委托?

applicationWillResignActive与applicationDidEnterBackground - 有什么区别?

此外,我注意到当传入的SMS或呼叫进入时,应用程序会调用applicationWillResignActive,但用户选择单击“确定”并继续。我不希望我的应用程序在这些情况下采取任何行动。我只是希望它继续运行而不进行任何中间清理,因为用户没有退出应用程序。所以,我认为在applicationDidEnterBackground中进行清理工作更有意义。

我将非常感谢您对最佳实践的意见,以便选择哪些代表实现唤醒和入睡,以及考虑被短信/电话打断等事件。

谢谢

ios objective-c iphone uiapplicationdelegate
6个回答
423
投票

当醒来,即重新启动应用程序(通过跳板,应用程序切换或URL)时,会调用applicationWillEnterForeground:。它只在应用程序准备好使用后执行一次,在放入后台后,而applicationDidBecomeActive:可能在启动后被多次调用。这使applicationWillEnterForeground:成为重新启动后只需要发生一次的设置的理想选择。

applicationWillEnterForeground:被称为:

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

applicationDidBecomeActive:被称为:

  • 当应用程序首次在application:didFinishLaunchingWithOptions:之后启动时
  • applicationWillEnterForeground:之后,如果没有要处理的URL。
  • application:handleOpenURL:被召唤之后。
  • applicationWillResignActive:之后,如果用户忽略中断,如电话或短信。

applicationWillResignActive:被称为:

  • 当像电话那样中断时。 如果用户接听电话applicationDidEnterBackground:被调用。 如果用户忽略调用applicationDidBecomeActive:被调用。
  • 当按下主页按钮或用户切换应用程序时。
  • 医生说你应该 暂停正在进行的任 禁用计时器 暂停比赛 降低OpenGL帧速率

applicationDidEnterBackground:被称为:

  • applicationWillResignActive:之后
  • docs说你应该: 发布共享资源 保存用户数据 使计时器无效 保存应用程序状态,以便在应用程序终止时恢复它。 禁用UI更新
  • 你有5秒的时间来做你需要的并返回方法 如果你在约5秒内没有返回应用程序终止。 你可以向beginBackgroundTaskWithExpirationHandler:索要更多时间

The official documentation.


26
投票

This Apple Document对您的问题很有帮助。对于快速概念,您可以在该文档中看到图2-3。您还可以从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:.
     */
}

在上面的代码中,只有应用程序启动才有机会说“是”或“否”,其他只是通知。换句话说,您无法通过上面的代码列表强制用户忽略来电或短信。不知道是否还有其他解决方法。


13
投票

我仍然对Dano的答案感到困惑,所以我做了一些测试来获取某些场景中的事件流程供我参考,但它也可能对你有用。这适用于不在其info.plist中使用UIApplicationExitsOnSuspend的应用。这是在iOS 8模拟器上进行的+使用iOS 7设备确认的。请原谅Xamarin的事件处理程序名称。它们非常相似。

  • 从未运行状态启动的初始和所有后续启动:

FinishedLaunching

OnActivated

  • 中断(电话,顶部滑下,底部上滑):
  • 主页按钮双击列出非活动应用程序,然后重新选择我们的应用程序:

OnResignActivation


OnActivated

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

OnResignActivation

DidEnterBackground


WillEnterForeground

OnActivated

  • 主页按钮双击,并终止我们的应用程序:(后续重新启动是第一种情况)

OnResignActivation

DidEnterBackground

DidEnterBackground(仅限iOS 7?)

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


9
投票

applicationWillEnterForeground被称为:

当应用程序重新启动时(从背景到前景)当app首次启动时,即调用applicationDidFinishLaunch时,不会调用此方法,但仅限于来自背景applicationDidBecomeActive

applicationDidBecomeActive被称为

didFinishLaunching之后的applicationWillEnterForeground首次启动app时,如果没有要处理的URL。在application:handleOpenURL:被召唤之后。在applicationWillResignActive之后,如果用户忽略中断,如电话或短信。在应用程序的任何地方消失alertView之后


7
投票

当系统要求权限时,将调用applicationWillResignActive。 (在iOS 10中)。万一有人遇到和我一样的麻烦......


5
投票

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

在iOS 7中,如果用户接听电话,则调用applicationWillResignActive:和applicationDidEnterBackground :.但是在iOS 8+中只调用applicationWillResignActive :.

© www.soinside.com 2019 - 2024. All rights reserved.