如何使用beginBackgroundTaskWithExpirationHandler在iOS中已运行的任务

2020/12/17 04:22 · ios ·  · 0评论

在我的应用中,我正在将图像从iPhone上传到服务器。在同步过程中,如果用户按下主页按钮,则应用程序将关闭。

我希望应用程序必须在后台运行,直到同步完成。

我的问题是:如何添加带有“ beginBackgroundTaskWithExpirationHandler”的当前正在运行的任务

请分享您的想法。

尽管名称如此,beginBackgroundTaskWithExpirationHandler:实际上并没有“开始”任务。最好将其视为“注册...”而不是“开始....”。您只是在告诉系统您正在做一些可以完成的事情。

几点:

  • 在几乎所有情况下,您都想beginBackgroundTaskWithExpirationHandler:在开始做自己想做的事情时打电话给您,然后endBackgroundTask:在完成时打电话给您几乎永远不会在用户按下“主页”按钮时调用这些命令(除非这是您启动任务的时间,例如将某些内容保存到服务器)。

  • 您可以一次打开任意多个“后台任务”。他们不花钱。他们就像保留计数。只要您还有一个打开(“开始”没有到达“结束”),系统就会认为该请求需要更多时间。调用“ begin”和“ end”方法的成本很小,因此可以使用它们将需要额外时间来完成的内容括起来。

  • 无法确定您将完成同步。这些方法只是发出请求。操作系统可能仍然拒绝该请求。操作系统可能在需要一些额外资源的时候仍然会杀死您。操作系统并非无限耐心;如果您花费的时间太长(通常约10分钟),则在调用到期处理程序后,它将杀死您。操作系统可能会杀死您,因为手机已关闭。您的应用程序必须能够处理无法完成的工作。操作系统仅为您提供了此功能,以便您可以改善用户体验。

我将以下代码用于后台任务处理程序:

__block UIBackgroundTaskIdentifier backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{

    NSLog(@"Background Time:%f",[[UIApplication sharedApplication] backgroundTimeRemaining]);

    [[UIApplication sharedApplication] endBackgroundTask:backgroundTaskIdentifier];

    backgroundTaskIdentifier = UIBackgroundTaskInvalid;
}];

这是我使用beginBackgroundTaskWithExpirationHandler的方法,包括对在后台完成的方法的调用。这包括用于启动新的异步任务的代码。因此,不完全是问题中要问的内容。在下面添加代码,以为有人可能正在寻找这种情况:

- (void)didReceiveObjList:(CFDataRef)message
{
  // Received Object List. Processing the list can take a few seconds.
  // So doing it in separate thread with expiration handler to ensure it gets some time to do     the task even if the app goes to background.

  UIApplication *application = [UIApplication sharedApplication];
  __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      [self processObjList:message];

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

  NSLog(@"Main Thread proceeding...");

}

看看此页面,Apple描述了如何使iOS应用程序在后台时不暂停。
苹果资料

这是我已经实现的:

UIBackgroundTaskIdentifier bgTask;

- (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.
    NSLog(@"=== DID ENTER BACKGROUND ===");
    bgTask = [[UIApplication  sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        NSLog(@"End of tolerate time. Application should be suspended now if we do not ask more 'tolerance'");
        // [self askToRunMoreBackgroundTask]; This code seems to be unnecessary. I'll verify it.
    }];

    if (bgTask == UIBackgroundTaskInvalid) {
        NSLog(@"This application does not support background mode");
    } else {
        //if application supports background mode, we'll see this log.
        NSLog(@"Application will continue to run in background");  
    }
}

/*

- (void)askToRunMoreBackgroundTask
{
    [[UIApplication sharedApplication] endBackgroundTask:bgTask];
    NSLog(@"restart background long-running task");
    bgTask = [[UIApplication  sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        NSLog(@"End of tolerate time. Application should be suspended now if we do not ask more 'tolerance'");
        [self askToRunMoreBackgroundTask]; 
    }];

}

*/

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSLog(@"=== GOING BACK FROM IDLE MODE ===");
    //it’s important to stop background task when we do not need it anymore
    [[UIApplication sharedApplication] endBackgroundTask:UIBackgroundTaskInvalid];  
}

当应用程序进入后台时,我使用的其他答案略有不同,我需要在主线程上做一些事情:

- (void)applicationWillResignActive:(UIApplication *)application
{
     UIApplication *app = [UIApplication sharedApplication];

    // Register auto expiring background task
    __block UIBackgroundTaskIdentifier bgTaskId =
        [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:bgTaskId];
        bgTaskId = UIBackgroundTaskInvalid;
    }];

    // Execute background task on the main thread
    dispatch_async( dispatch_get_main_queue(), ^{
        // ------------------
        // DO SOMETHING INVOLVING THE WEBVIEW - WHICH MUST OCCUR ON THE MAIN THREAD!
        // ------------------
        [app endBackgroundTask:bgTaskId];
        bgTaskId = UIBackgroundTaskInvalid;
    });
}

beginBackgroundTaskWithExpirationHandler当应用程序将应用程序的状态更改为后台时,您应该在之后运行任务或捕获通知,然后取消当前任务并使用再次运行beginBackgroundTaskWithExpirationHandler

本文地址:http://ios.askforanswer.com/ruheshiyongbeginbackgroundtaskwithexpirationhandlerzaiioszhongyiyunxingderenwu.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!