ios 实现在后台运行的长期任务

       当用户点击home键,ios系统会让我们的程序进入到后台状态,对于许多应用来说,程序进入到后台后会被挂起,挂起应用能够提高电池的使用时间,还能让ios把重要的系统资源分配给正在前台运行的程序。

      但是在有些情况下,我们需要程序在进入后台时仍然正常运行,比如一个徒步类的应用,它需要一直记录用户的位置,来生成一张用户的路线图。一个音频应用在用户锁屏期间仍能播放音乐.还有一些应用可能需要在后台下载数据,在应用进入到前台时,直接显示。(缩短用户的等待时间)。当我们觉得自己的应用需要在后台长时间运行时,ios系统为我们提供了三种方法来实现这个种机制:

    1. 在前台启动了一个短期任务的应用在程序进入到后台进,可以向ios系统要一点时间来完成这个短期任务

     2.在前台启动了一些下载任务的应用可以把那些下载任务移交给ios系统管理。当程序被挂起或被用户结束的时候,仍能继续下载。

    3. 那些需要在后台运行的应用可以根据执行的需要来声明他们需要的后台运行模式

    我们应避免任务在后台运行,除非这个后台任务能提高应用的整体用户体验。在用户启动了一个新的应用或用户锁屏会使用我们的应用进入到后台,这两种情况下,用户的想法是:“我现在不需要再使用这个应用了,我想玩玩别的”。在这种情况下,如果应用仍在后台运行会非常的费电,可能会让用户强行退出我们的应用。所以一定要仔细斟酌我们的应用是否真的需要在后台运行。


  执行短期任务(运行时间有限的任务)

 正常情况下,一个应用进行到后台时,正在执行的任务会被挂起,我们可以调用 beginBackgroundTaskWithName:expirationHandler 和beginBackgroundTaskWithExpirationHandler: 方法向ios系统再要一点时间来把任务执行完。(也就是说这两个方法可以让我们的应用过一段时间后才被挂起)

在任务完成后,我们的应用必须调用endBackgroundTask来告诉ios系统,任务执行完啦。现在你可以挂起我的应用了。

 每次调用beginBackgroundTaskWithName 或 beginBackgroundTaskWithExpirationHandler 都生返回一个唯一的标识,(这个标识用来与我们在后台执行的任务一一对应),当在后台执行的任务执行完毕后,必须调用endBackgroundTask来告诉ios系统任务执行完毕了(endBackgroundTask需要上面的标识来做为参数,表明对应的任务结束了)。如果不调用endBackgroundTask,应用会被结束掉。如果我们提供了ExpirationHandler方法的话,ios系统会调用它,来给我们机会调用endBackgroundTask.


  我们不需要等到程序进入到后台时再开启一个后台任务(废话,等一下有个标准用户的demo),更好的设计方案是:在开启一个任务前调beginBackgroundTaskWithName or beginbackgroundTaskWithExpirationHandler 然后在任务完成时调用endBackgroundTask。

 下面的demo演示了在我们的应用进行到后台时如何开启一个长期运行的任务。在这个demo中,开始后台任务进使用了一个expiration handler 来防止任务运行超时。任务被添加到一个全局队列中异步执行,来保存在执行applicationDidEnterBackground方法能正常返回。

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
        // Clean up any unfinished task business by marking where you
        // stopped or ending the task outright.
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];
 
    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 
        // Do the work associated with the task, preferably in chunks.
 
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
}

Note: Always provide an expiration handler when starting a task, but if you want to know how much time your app has left to run, get the value of the backgroundTimeRemaining property of UIApplication.



 注意:一定要为 expirationHandler指定一个代码块,在这个代码块中判断任务是执行完毕,如果没有执行完毕,关闭任务,再关闭对应的后台任务(
endBackgroundTask
),当ios系统执行expirationHandler时,说明我们的应用马上就要被挂起了,所以在这个方法中执行的代码一定要精简。(就是不能执行太耗时的操作。)


在后台进行下载任务

  






 



 

你可能感兴趣的:(ios运行机制)