0

我想知道是否有办法让应用程序在特定的间隔时间内保持在前台运行。

我有一个线程在 3 分钟内准确运行,我需要用户不能离开应用程序。如果这样的事情是不可能的,我会问另一个问题。

我可以让用户将应用程序设置为后台模式,因为我使用该applicationDidEnterBackground:(UIApplication *)application方法来保存我需要的数据,但是如果用户单击电源按钮,我该如何保存数据?

applicationWillTerminate:(UIApplication *)application被称为?有什么解决办法吗?

4

2 回答 2

2

您可能需要查看beginBackgroundTaskWithExpirationHandler,它可以让您的应用程序在后台运行时请求额外的处理时间来完成任务。

也就是说,不建议您这样做。您应该确保您的应用程序可以从您的三分钟任务中恢复,以防意外终止或失败。例如,您的应用程序可能会因内存不足而意外崩溃或终止 - 在这些情况下,您不会收到对applicationWillTerminate或的任何回调applicationDidEnterBackground

因此,我的建议是考虑使用 iOS 的后台任务支持,以便在用户离开应用程序时让您的保存在后台继续,但还要确保如果您的应用程序在没有警告的情况下被系统终止,您的任务是可恢复的/可以安全地被重绕。

于 2013-03-11T09:54:37.613 回答
0

您需要使用beginBackgroundTaskWithExpirationHandler来处理您的进程。使用此代码。

在这里,我从 applicationDidEnterBackground:(UIApplication *)application 调用此方法以将数据存储在 SQlite 中,即使应用程序进入后台或 UIApplicationStateInactive(按电源按钮)。如果 application.backgroundTimeRemaining 为 0,则根据 IOS 标准,保存过程将持续 10 分钟 使用此代码并自定义您的流程。

-(void)handleBackgroundSavingingProcess:(UIApplication *)application
    {
        NSLog(@"background task remaining time before background %f",application.backgroundTimeRemaining);

        if ((([application applicationState] == UIApplicationStateBackground) || ([application applicationState] == UIApplicationStateInactive)) && [application respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)])
  {


     self.bgTaskId = [application beginBackgroundTaskWithExpirationHandler:^{
     // Synchronize the cleanup call on the main thread in case
     // the task actually finishes at around the same time.
                NSLog(@"background task remaining time in expiration handler %f",application.backgroundTimeRemaining);

                dispatch_queue_t concurrentQueue;
                if([[[UIDevice currentDevice] systemVersion] doubleValue] >= 5.0)
                    concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0UL);
                else
                    concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL);

                if (concurrentQueue == nil)
                    return;

                dispatch_async(concurrentQueue, ^{

                    if (self.bgTaskId != UIBackgroundTaskInvalid){
                        NSLog(@"background task remaining time in dispatch queue %f",application.backgroundTimeRemaining);
                        NSLog(@" Downloading status %d",self.isDownloadingInComplete);
                        if(self.isDownloadingInComplete)
                        {
                            [application presentLocalNotificationNow:localNotification];
                            NSLog(@"Local notification fired.");
                        }
                        [DataManager managedObjectContext] save:nil];
                        [application endBackgroundTask:self.bgTaskId];
                        self.bgTaskId = UIBackgroundTaskInvalid;
                        NSLog(@"Initialization invalid.");
                    }
                });
            }];
        }

    }
于 2013-03-11T10:21:44.747 回答