225

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

applicationWillEnterForeground vs applicationDidBecomeActive——有什么区别?

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

applicationWillResignActive 与 applicationDidEnterBackground - 有什么区别?

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

我希望您能就最佳实践提供意见,以便选择实施哪些代表以实现唤醒和睡眠,以及考虑诸如被短信/电话打断等事件。

谢谢

4

7 回答 7

467

唤醒时,即重新启动应用程序(通过跳板、应用程序切换或 URL)applicationWillEnterForeground:被调用。它只在应用程序可以使用时执行一次,在进入后台后执行,而applicationDidBecomeActive:在启动后可能会被多次调用。这applicationWillEnterForeground:非常适合需要在重新启动后进行一次的设置。

applicationWillEnterForeground:叫做:

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

applicationDidBecomeActive:叫做:

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

applicationWillResignActive:叫做:

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

applicationDidEnterBackground:叫做:

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

官方文档。

于 2012-03-25T13:15:38.127 回答
28

管理应用程序的生命周期有助于解决您的问题。对于快速概念,您可以查看该文档中的图形。您还可以阅读 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官方文档

于 2011-11-10T08:05:25.760 回答
13

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

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

完成发射

已激活

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

OnResignActivation


已激活

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

OnResignActivation

DidEnterBackground


将进入前台

已激活

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

OnResignActivation

DidEnterBackground

DidEnterBackground(仅限 iOS 7?)

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

于 2014-09-23T01:27:07.613 回答
9

applicationWillEnterForeground叫做:

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

applicationDidBecomeActive叫做

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

于 2014-11-04T01:15:28.753 回答
7

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

于 2016-12-03T00:44:02.407 回答
5

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

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

于 2015-01-30T05:54:20.533 回答
4

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

- (void)sceneWillEnterForeground:(UIScene *)scene
- (void)sceneDidBecomeActive:(UIScene *)scene
于 2020-01-12T23:24:07.357 回答