applicationWillEnterForeground与applicationDidBecomeActive,applicationWillResignActive与applicationDidEnterBackground

时间:2010-09-14 21:15:46

标签: ios objective-c iphone uiapplicationdelegate

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

applicationWillEnterForeground vs applicationDidBecomeActive - 有什么区别?

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

applicationWillResignActive与applicationDidEnterBackground - 有什么区别?

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

我很感激您对最佳实践的意见,以便选择要唤醒和入睡的代表,以及考虑被短信/电话中断等事件。

由于

7 个答案:

答案 0 :(得分:413)

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

applicationWillEnterForeground:被称为:

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

applicationDidBecomeActive:被称为:

  • application:didFinishLaunchingWithOptions:
  • 之后首次启动应用时
  • applicationWillEnterForeground: 后,如果没有要处理的网址。
  • 在调用application:handleOpenURL:之后。
  • applicationWillResignActive: 之后
  • 如果用户忽略了电话或短信等中断。

applicationWillResignActive:被称为:

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

applicationDidEnterBackground:被称为:

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

The official documentation.

答案 1 :(得分:25)

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:.
     */
}

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

答案 2 :(得分:13)

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

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

FinishedLaunching

     

OnActivated

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

OnResignActivation

     
     

OnActivated

  • 主页按钮双击列出非活动应用,选择其他应用,然后重新启动我们的应用:
  • 按住主页按钮,然后重新启动:
  • 锁定(开/关按钮),然后解锁:
  

OnResignActivation

     

DidEnterBackground

     
     

WillEnterForeground

     

OnActivated

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

OnResignActivation

     

DidEnterBackground

     

DidEnterBackground(仅限iOS 7?)

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

答案 3 :(得分:9)

applicationWillEnterForeground被称为:

当app重新启动时(来自后台到前台) 当应用程序第一次启动时,即调用applicationDidFinishLaunch但仅来自后台时,不会调用此方法 applicationDidBecomeActive

applicationDidBecomeActive被称为

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

答案 4 :(得分:7)

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

答案 5 :(得分:5)

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

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

答案 6 :(得分:2)

对于iOS 13+,将执行以下方法:

- (void)sceneWillEnterForeground:(UIScene *)scene
- (void)sceneDidBecomeActive:(UIScene *)scene