应用进入前台时取消后台任务

Posted

技术标签:

【中文标题】应用进入前台时取消后台任务【英文标题】:Cancel background task when app enters foreground 【发布时间】:2012-10-14 13:29:30 【问题描述】:

在我的应用程序中,当用户关闭应用程序(即进入后台)时,我正在将我的数据与服务器同步。这个过程大约需要一分钟,并且涉及到对服务器的各种调用以上传数据,因此我选择将其作为后台线程执行。

- (void)applicationDidEnterBackground:(UIApplication *)application 

    bgTask = [application beginBackgroundTaskWithExpirationHandler:^
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    ];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
        [asynchronousAPIController processQueueOrWaitWithIsBackgroundSync:true];

        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    );

这可以正常工作,除非用户在此同步期间(即第一分钟)重新进入前台。我想要是让后台同步终止完成 - 即使它在同步过程中也停止同步。当app下一次进入后台时,它可以从头开始整个过程​​,没问题。

我试过用这个:

- (void)applicationWillEnterForeground:(UIApplication *)application 
    if (bgTask != UIBackgroundTaskInvalid) 
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    

但它不会停止同步 - 只会继续进行。几乎就像一旦开始,它就会继续前进。

我怀疑这可能是因为控制同步的对象是单例——也就是说,它不是一个可以被销毁的类对象,而是一个单例,因此可能会因此而存活。这会有所作为吗?

还是我做错了什么?

任何建议,非常感谢。

【问题讨论】:

【参考方案1】:

您需要在 NSOperation 中进行后台工作。我会创建一个 NSBlockOperation 并将其添加到 NSOperationQueue。这样一个后台线程就会自动产生。对于复杂的操作,创建一个 NSOperation 子类。 在 NSOperation 代码中检查操作是否定期取消(例如在 for 循环中),如果是则退出代码块(在 for 循环中:if ([operation isCanceled]) break;)。 在 applicationWillEnterForeground 中只是取消操作。

【讨论】:

菲克斯!谢谢!我按照您的建议做了,然后回来查看操作是否已取消并且一切正常。你是救生员!

以上是关于应用进入前台时取消后台任务的主要内容,如果未能解决你的问题,请参考以下文章

当应用程序进入后台时,在前台执行的长时间运行的任务被挂起

如果前台应用程序终止,如何通知后台任务?

Visual Studio 2013 - 添加对前台应用程序和后台任务的相同引用

后台任务永远运行?

如何把linux后台任务调到前台

当应用程序进入后台时,它的静态实例可能会被清除吗?