当 iOS 应用程序进入后台时,是不是会暂停冗长的任务?

Posted

技术标签:

【中文标题】当 iOS 应用程序进入后台时,是不是会暂停冗长的任务?【英文标题】:When an iOS application goes to the background, are lengthy tasks paused?当 iOS 应用程序进入后台时,是否会暂停冗长的任务? 【发布时间】:2011-10-02 19:17:45 【问题描述】:

是的,我知道如果我希望我的应用能够响应用户的多任务操作,例如切换到另一个应用,我应该处理

- (void)applicationWillResignActive:(UIApplication *)application
- (void)applicationDidBecomeActive:(UIApplication *)application

如果我的应用正在执行一个相当耗时的操作(例如下载一个大文件)并且用户让我的应用进入后台怎么办?当用户返回我的应用时,该操作是否会自动暂停和恢复?

当我的应用进入后台或在前台恢复时,幕后究竟会发生什么?

如果当用户让我的应用程序进入后台时,我的应用程序的执行只是在一个方法的中间呢?

例如,我的应用正在做

for (int i = 1 to 10000K) 
    do some calculation;

当 i== 500K 时,用户切换到另一个应用。我的应用程序中的 for 循环会发生什么?

【问题讨论】:

我认为这是一个很好的问题,但是您是否真的花时间测试并弄清楚当它进入后台时会发生什么?我的意思是,将 NSLog 放在循环中的某个地方,看看会发生什么...... 首先,建议遵循以下 micpringle 的建议。其次,如果我没记错的话,是不是有七个非常具体的 API 可以在后台运行?看看这些,看看它们是否符合要求。如果他们不这样做,也许你需要重新设计你的应用程序做事的方式。 【参考方案1】:

来自ios App Programming Guide:

您的应用委托的 applicationDidEnterBackground: 方法具有 大约 5 秒完成任何任务并返回。在实践中, 此方法应尽快返回。如果该方法确实 在时间用完之前不返回,您的应用程序将被杀死并清除 记忆。如果您仍需要更多时间来执行任务,请致电 beginBackgroundTaskWithExpirationHandler: 请求后台的方法 执行时间,然后在辅助服务器中启动任何长时间运行的任务 线。无论您是否启动任何后台任务, applicationDidEnterBackground: 方法仍必须在 5 内退出 秒。

如果您上面描述的长时间运行的操作在主线程上,并且在您的应用程序进入后台后需要超过 5 秒才能完成,您的应用程序将被终止。主线程将被阻塞,你将没有机会及时从-applicationDidEnterBackground:返回。

如果您的任务在后台线程上运行(确实应该是,如果它需要很长时间才能执行),如果应用程序从 -applicationDidEnterBackground: 返回(根据 this answer 中的讨论),该线程似乎已暂停)。当应用程序回到前台时,它将被恢复。

但是,在后一种情况下,您仍应准备好在应用程序处于后台时随时终止应用程序,方法是在前往后台的路上进行清理。

【讨论】:

这令人困惑。 beginBackgroundTaskWithExpirationHandler 授予您的应用程序 10 分钟(很多!)来完成任务,但“仍然为您的应用程序在后台随时终止做准备” ???哪个是真的?我大约 10 秒的任务是使用 CoreGraphics 渲染图像(作为缩略图)并在后台任务中处理它们,它们挂了!!!当应用程序进入后台时永远。在“beginBackgroundTaskWithExpirationHandler”期间允许应用程序做什么?【参考方案2】:

如果您正在执行一些可能会消耗时间的操作并且您不想杀死它,那么您可以通过在 UIBackground Task i 中执行来延长您的操作时间


    UIBackgroundTaskIdentifier  taskId = 0;
    taskId = [application beginBackgroundTaskWithExpirationHandler:^
        taskId = UIBackgroundTaskInvalid;
    ];

// Execute long process. This process will have 10 mins even if your app goes in background mode.


名为“handler”的块参数是后台任务到期(10分钟)时发生的事情。 这是documentation的链接

【讨论】:

这在应用程序进入后台时有效。应用程序被杀死时的解决方案是什么,例如applicationWillTerminate(_ application: UIApplication) 你能详细说明一下吗? 1.) 什么是调用 'beginBackgroundTaskWithExpirationHandler' 的正确时间?我可以从 'applicationWillResignActive' 或 'applicationDidEnterBackground' 中做到这一点吗? 2.) 应用程序在后台时是否会调用过期处理程序?在什么线程/队列上?在这个处理程序中可以做什么,什么不能? 3.) 我的应用程序使用 CoreGraphics 在后台渲染图像 - 一些 CG 方法将它们的线程挂在后台。他们会在这样的“背景任务”中生存得更好吗???【参考方案3】:

如上所述,在某些情况下,您的应用在后台运行,Apple 可以根据您的操作允许或拒绝。

https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html

更重要的是,如果您确实属于这些类别之一,那么您的应用刷新率是由苹果算法确定的,该算法会考虑您在该设备上的应用与其他应用的使用情况。如果您的应用程序使用更频繁,那么它会分配更多的后台时间。这只是一个变量,但您会发现后台时间分配因应用而异,不受您的控制。

【讨论】:

以上是关于当 iOS 应用程序进入后台时,是不是会暂停冗长的任务?的主要内容,如果未能解决你的问题,请参考以下文章

当应用程序进入和退出后台时更新ios中的计时器

应用程序在后台或暂停时的位置更新

当应用程序进入暂停状态时取消本地通知。(从后台删除)

当应用程序进入后台时暂停和恢复 UIView 动画

当后台服务取消暂停或重新启动时,iOS 应用程序需要多长时间?

应用程序进入后台时暂停音频