ChatGPT解决这个技术问题 Extra ChatGPT

applicationWillEnterForeground 与 applicationDidBecomeActive、applicationWillResignActive 与 applicationDidEnterBackground

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

applicationWillEnterForeground vs applicationDidBecomeActive——有什么区别?

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

applicationWillResignActive 与 applicationDidEnterBackground - 有什么区别?

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

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

谢谢


C
Cœur

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

applicationWillEnterForeground: 被调用:

当应用程序重新启动时

在 applicationDidBecomeActive 之前:

applicationDidBecomeActive: 被调用:

在应用程序之后首次启动应用程序时:didFinishLaunchingWithOptions:

在 applicationWillEnterForeground: 之后如果没有要处理的 URL。

在 application:handleOpenURL: 被调用之后。

在 applicationWillResignActive 之后:如果用户忽略了电话或短信等中断。

applicationWillResignActive: 被调用:

当有电话等中断时。如果用户调用 applicationDidEnterBackground: 被调用。如果用户忽略调用 applicationDidBecomeActive: 被调用。

如果用户调用 applicationDidEnterBackground: 被调用。

如果用户忽略调用 applicationDidBecomeActive: 被调用。

当按下主页按钮或用户切换应用程序时。

文档说你应该暂停正在进行的任务禁用计时器暂停游戏降低 OpenGL 帧速率

暂停正在进行的任务

禁用计时器

暂停游戏

降低 OpenGL 帧速率

applicationDidEnterBackground: 被调用:

申请WillResignActive后:

文档说你应该:释放共享资源保存用户数据无效计时器保存应用程序状态,以便在应用程序终止时恢复它。禁用 UI 更新

释放共享资源

保存用户数据

使计时器无效

保存应用程序状态,以便在应用程序终止时恢复它。

禁用 UI 更新

如果您在约 5 秒内未返回应用程序终止,您有 5 秒的时间做您需要做的事情并返回该方法。您可以使用 beginBackgroundTaskWithExpirationHandler 请求更多时间:

如果您在约 5 秒内未返回,则应用程序将被终止。

您可以使用 beginBackgroundTaskWithExpirationHandler 请求更多时间:

The official documentation.


还有一件事要补充。如果您从您的应用(双击主页按钮)打开后台应用列表,然后返回到它(选择您的应用的预览) - -applicationWillEnterForeground: 不会被调用,只有 -applicationDidEnterBackground:(假设,iOS 不认为这是重新启动)。
@kpower 是的,那只是打破了我的脖子......从没想过 willEnterForeground 在这种情况下不会被调用......
不是每次从后台到前台都会调用applicationWillEnterForeground:吗?!我找不到事后没有 applicationDidBecomeActive 的情况。
这是不准确的。可以在没有 applicationDidEnterBackground 的情况下调用 applicationWillResignActive
t
tomjpsun

Managing Your App's Life Cycle 对您的问题很有帮助。对于快速概念,您可以查看该文档中的图形。您还可以阅读 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的官方文档


链接已失效。
修改一些描述和链接,现在是 2019 年。
C
Community

我仍然对 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 设备上进行测试。当我得到答案时,我会更新我的答案,或者其他人可以确认。


m
mfaani

applicationWillEnterForeground 被称为:

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

applicationDidBecomeActive 被调用

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


你有没有机会知道这是否从 iOS 7 开始改变?我记得(我可能弄错了)在 applicationWillEnterForeground 中做一些事情(iOS 5/6)并在应用程序首次启动时运行。截至目前,在 7.1/8 中,您是对的 applicationWillEnterForeground 在启动时不会被调用。
A
Anson Yao

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


知道权限弹出关闭后调用什么方法吗?我有这个问题stackoverflow.com/questions/26059927/…
Q
Qiulang

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

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


u
user2994130

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

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

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅