ios background task


今天要实现一个需求,当用户触摸HOME键,将应用切换到后台时,启动自动备份的任务。这涉及到ios的后台任务处理,本文简单总结一下

首先,ios app有5种状态,分别是:not running, inactive, active, background, suspended,详情请看官方的guide:

apple guide

机制

如果应用处于background状态,又希望它继续做一些事的话,ios提供了几种途径:

推送

苹果提供的PUSH机制,叫APNS。腾讯的QQ和微信就是使用这种方式。实际上,使用长连接会更好,但是苹果不支持。我理解其实应用已经suspended,但是当接收到push的数据以后,会短暂地回到background进行处理,处理完毕以后又回到suspended状态

从ios7开始,分为local push和remote push,我们应用现在还没用到,暂不深究

智能调度

太玄乎了,不太了解

特定的多任务

某些特定的任务可以在后台长时间运行,比如VOIP,location service等,只有特定类型的任务,才能用这种方式,适用性不强

后台上传下载

类似于特定多任务,只有特殊的任务才能用

task completion

这种方式的适用性比较强,我最后也是采取这种方式来实现的。因此本文重点介绍这种

通常情况下,应用在进入background之后,很快就会转到suspended状态。但是,如果应用有需要的话(比如我们这个需求),可以向系统申请一点额外的时间来完成当前的任务

代码:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

- (void)applicationDidEnterBackground:(UIApplication *)application

{

    __block UIBackgroundTaskIdentifier bgTask;// 后台任务标识

    

    // 结束后台任务

    void (^endBackgroundTask)() = ^(){

        [application endBackgroundTask:bgTask];

        bgTask = UIBackgroundTaskInvalid;

    };

    

    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{

        endBackgroundTask();

    }];

    

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        

        double start_time = application.backgroundTimeRemaining;// 记录后台任务开始时间

        

        BOOL networkAvailable = [YLSGlobalUtils isNetworkAvailable];

        if(!networkAvailable){

            NSLog(@"网络不可用,取消自动备份");

            endBackgroundTask();

            return;

        }

        

        BOOL need = [backupService checkNeedBackup];

        if(!need){

            NSLog(@"无需备份");

            endBackgroundTask();

            return;

        }

        

        [backupService doBackupProcessHandler:^(float done, float total){

            // nothing to do with progress

        } CompletionHandler:^(NSError* error, NSArray* statistics){

            double done_time = application.backgroundTimeRemaining;

            double spent_time = start_time - done_time;

            NSLog(@"后台备份完成,耗时: %f秒", spent_time);

            endBackgroundTask();

        }];

    });

}

核心是这个方法:

?


1

- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void(^)(void))handler

注册一个后台任务,这个任务最多只有10分钟时间,如果超时,则会调用参数中的block,在此block中,必须调用这个方法:

?


1

- (void)endBackgroundTask:(UIBackgroundTaskIdentifier)identifier

否则,应用会crash。只要调用了beginBackgroundTaskWithExpirationHandler:方法,就必须在handler里相应地调用endBackgroundTask:方法

实际的逻辑,在下面的block里完成,这里没什么特别的,只是如果提前结束了任务,也调用一次endBackgroundTask:方法,这样就不会超时,前面的expirationHandler就不会被执行

另外,通过UIApplication的backgroundTimeRemaining属性,可以获取此后台任务还剩余的时间(当此值变成0,expirationHandler就被执行)

使用时机

这段代码,是写在ApplicationDelegate的生命周期方法里:

?


1

- (void)applicationDidEnterBackground:(UIApplication *)application

这主要是因为,我们就是希望仅当应用被切换到后台时才开始自动备份。但是后台任务并不是只能在这种情况下启动,如果应用中有一些关键性的任务,希望即使被切换到后台也要先完成再suspend,就可以随时调用

?


1

- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void(^)(void))handler

以确保此任务完成,写法只要参考上面的代码就行了

时间: 2024-11-11 22:31:54

ios background task的相关文章

iOS 后台任务之 Long-running background task

项目里遇到需求需要App进入后台还能执行一些任务,于是便Google了一下,整理一篇小记录. 大家都知道iOS系统里,所有App进入后台的时候默认都是会暂停所有线程,等到再双击Home键回到前台才会继续执行.那有的场景需要在后台进行upload.download,或者进行一些计算等等怎么办呢? iOS7推出了一些新的API,让,那就是 NSURLSession ,就是为了取代前 NSURLConnection而生,在我们常用的 AFNetworking 2.0 中也新增了对其的支持 (AFURL

UWP -- Background Task 深入解析

原文:UWP -- Background Task 深入解析 1. 重点 锁屏问题 从 Windows 10 开始,用户无须再将你的应用添加到锁屏界面,即可利用后台任务,通用 Windows 应用必须在注册任何后台触发器类型之前调用 RequestAccessAsync: await BackgroundExecutionManager.RequestAccessAsync(); 资源限制 由于对于内存较低的设备的资源约束,后台任务可能具有内存限制,该限制决定了后台任务可以使用的内存上限 在内存

IOS Background 之 Background Fetch

http://www.ithao123.cn/content-1363653.html 定期更新数据的app,比如及时通信类,微博等app 设置->通用->后台应用程序刷新. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中添加:[[UIApplication sharedApplication] setMinimumBa

how to run a continuous background task on OpenShift

https://stackoverflow.com/questions/27152438/best-way-to-run-rails-background-jobs-with-openshift https://stackoverflow.com/questions/26818574/my-python-script-hosted-on-openshift-inside-the-openshift-cron-minutely-directo https://www.reddit.com/r/Py

iOS 后台运行实现 --备用

文一 我从苹果文档中得知,一般的应用在进入后台的时候可以获取一定时间来运行相关任务,也就是说可以在后台运行一小段时间. 还有三种类型的可以运行在后以,1.音乐2.location 3.voip 文二 在IOS后台执行是本文要介绍的内容,大多数应用程序进入后台状态不久后转入暂停状态.在这种状态下,应用程序不执行任何代码,并有可能在任意时候从内存中删除.应用程序提供特定的服务,用户可以请求后台执行时间,以提供这些服务. 判断是否支持多线程 UIDevice* device = [UIDevice c

关于iOS后台问题( 一 )(ios后台刷新,后台定位,后台下载,真后台)

关于iOS的后台,以下引用一些文段进行一下脑补,请同学们大致看一下,有个基础,原文出处 ----------------------------------------------------------------------------------------------- OS 7中,实际上APP拥有四种后台模式,无论是哪一种后台机制,均需要利用苹果给予的相应后台接口实现.IOS7系统中,开发者可以灵活利用多种后台接口(API)实现更加智能的应用操作.一,无后台仅推送第 一种后台方式为传统

iOS申请持续的后台时间

iOS申请持续的后台时间 分类:IOS开发相关 (877)  (0) 由于苹果的后台机制,当我们按下home键的时候,所有线程包括主线程的任务都会被挂起,一些资源比如socket也会被系统回收,会导致很多问题,比如一个很重要的资源中断下载,或者定时器方法被暂停等等. 苹果在4.0以后提供了一种申请后台时间的机制: - (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handl

IOS的APNS和PushKit门道详述

基本功 iOS在诞生之初为了最大程度的保证用户体验,做了一些高瞻远瞩且影响深远的设计.APNs(Apple Push Notification service)就是其中一项. 早期iOS设备的内存和CPU资源都很有限,为了让前台活跃的app拥有尽可能多的系统资源,以及节约设备电量,iOS一开始就“不允许”普通app的进程常驻后台.这个决定很大程度上保障了用户体验和延长了手机的待机时间,但app的开发商需要和他们的用户保持联系.开发商需要有一个稳定的网络通道能每隔一段时间推送新的内容到用户设备.A

iOS后台运行

我从苹果文档中得知,一般的应用在进入后台的时候可以获取一定时间来运行相关任务,也就是说可以在后台运行一小段时间.还有三种类型的可以运行在后以,1.音乐2.location3.voip 文二 在IOS后台执行是本文要介绍的内容,大多数应用程序进入后台状态不久后转入暂停状态.在这种状态下,应用程序不执行任何代码,并有可能在任意时候从内存中删除.应用程序提供特定的服务,用户可以请求后台执行时间,以提供这些服务. 判断是否支持多线程 UIDevice* device = [UIDevice curren