iOS申请持续的后台时间

iOS申请持续的后台时间

分类:IOS开发相关

(877)  (0)

由于苹果的后台机制,当我们按下home键的时候,所有线程包括主线程的任务都会被挂起,一些资源比如socket也会被系统回收,会导致很多问题,比如一个很重要的资源中断下载,或者定时器方法被暂停等等。

苹果在4.0以后提供了一种申请后台时间的机制:

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

声明:

标记要开始一个新的长期运行的后台任务

参数:
handler

应用程序后台剩余时间快到达为0的时候的一个处理回调,你应该使用这个回调来做一些清理工作和后台任务结束的标记,未能明确地结束任务将导致APP的终止,这个处理回调将在主线程中被同步调用,并立刻阻止app的暂停当app被通知的时候。

返回值:

一个新的后台任务的唯一的标示符,你必须将这个值传给endBackgroundTask:方法来标记任务的结束。如果无法在后台运行这个方法将返回UIBackgroundTaskInvalid。

描述:

这个方法会让你的app转到后台以后继续运行一段时间,你可以在一个任务未完成将会导致影响用户体验的情况下调用此方法。例如,你可以调用次方法来获取足够的时间来传输一个很重要的文件到远程服务器或者至少尝试标记一些错误。你不应该随意的调用这个方法来保持你的app在后台长期运行。

每一次调用此方法都应该有对应的endBackgroundTask:方法,app的后台运行时间是有限的(你可以通过backgroundTimeRemaining属性来获取这个可用时间)如果在这个时间耗尽之前你没有调用endBackgroundTask:方法来结束相应的每个后台任务,系统就会杀掉这个app。如果你提供了这个handler,系统将会在到期时间到达之前调用这个handler来给你这个机会来终止你的任务。

你可以在你应用程序执行的任何地方调用这个方法,你也可以多次调用这个方法来标记多个并行的后台任务,然而,每个任务必须分开终止,你可以通过这个方法的返回值来标记不同的任务。

为了便于调试,这个方法是基于调用函数或者方法的名称来为任务命名的,如果你需要自定义这个名称,可以使用beginBackgroundTaskWithName:expirationHandler:方法来代替。

这个方法可以在非主线程中安全调用。

注意:

如果你在调试后台任务遇到麻烦,你可以尝试使用beginBackgroundTaskWithName:expirationHandler:方法太替代这个方法,这个方法提供相同的功能但是可以给你一个调试可用的任务名称。

使用方法:

以下在子线程中打开一个定时器,并在应用程序进入到后台以后打开回调

[objc] view plain copy

  1. [[NSNotificationCenter defaultCenter]  addObserver:self selector:@selector(applicationDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
  2. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  3. NSTimer* timer = [NSTimer timerWithTimeInterval:10.0
  4. target:self
  5. selector:@selector(timerHandle)
  6. userInfo:nil
  7. repeats:YES];
  8. [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
  9. [[NSRunLoop currentRunLoop]run];
  10. });

以下回调方法是申请后台时间,当系统无法再给更多的时间的时候会调用handler中的block块,在这个block中,我们要做相应的清理工作并终止后台任务(备注:如果我们不调用endBackgroundTask:来终止相应的后台任务的话,好像还能继续运行后台任务,不知道为啥,苹果文档是说你不自己终止,系统会给你kill掉)

[objc] view plain copy

  1. -(void)applicationDidEnterBackground
  2. {
  3. UIApplication*  application = [UIApplication sharedApplication];
  4. bgTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{
  5. NSLog(@"Starting background task with %f seconds remaining", application.backgroundTimeRemaining);
  6. if (bgTaskIdentifier != UIBackgroundTaskInvalid)
  7. {
  8. [application endBackgroundTask:bgTaskIdentifier];
  9. bgTaskIdentifier = UIBackgroundTaskInvalid;
  10. }
  11. }];
  12. }

[objc] view plain copy

  1. - (void)timerHandle
  2. {
  3. NSLog(@"timerHandle");
  4. }

我在子线程中开启了一个定时器,每隔10秒打印一次timerHandle,我在应用程序进入到后台以后申请了更多的后台时间,因此,当我按下home或者锁屏的时候,定时器方法会继续调用。

我们把定时器方法修改如下:

[objc] view plain copy

  1. - (void)timerHandle
  2. {
  3. NSLog(@"timerHandle");
  4. UIApplication*  application = [UIApplication sharedApplication];
  5. if (bgTaskIdentifier != UIBackgroundTaskInvalid)
  6. {
  7. [application endBackgroundTask:bgTaskIdentifier];
  8. bgTaskIdentifier = UIBackgroundTaskInvalid;
  9. }
  10. }

当定时器一启动我们就按下home键,在第一个10秒会打印timerHandle,然后应用程序会终止后台任务,直到我们重新进入到前台,才会继续打印信息。

同理,如果我此时是在后台下载文件,完成以后应该通过以上方法来终止相应的后台任务,按照苹果文档说的不能什么事情也没干还让程序在后台运行,

以上的bgTaskIdentifier是全局的UIBackgroundTaskIdentifier型变量,用来标示不同的后台任务的。比如说我有一个定时器需要后台运行,还有一个文件需要后台下载,那么我们就要通过这个不同的标示符来分开申请后台时间,并在后台完成任务以后分别去终止相应地后台任务。

时间: 2024-10-29 19:10:26

iOS申请持续的后台时间的相关文章

iOS 程序退到后台,如何继续执行任务

程序从前台退到后,将执行程序的委托方法. - (void)applicationDidEnterBackground:(UIApplication *)application { } 问题: 当应用被送到后台,主线程就会被暂停.用 NSThread 的 detachNewThreadSelector:toTar get:withObject:类方法创建的线程也被挂起. 场景: 应用从前台退到后台 程序执行代理方法 applicationDidEnterBackground.这时候,我们只有很短的

请求更多后台时间-陈棚

假如应用程序正在知心文件下载或者文件传输等,当应用进入后台时,如果该任务还没有执行王成,应用转入后提啊后,该任务就会被暂停.千万不要强制在applicationDidenterBackGround:方法中直接完成改任务--因为这回导致应用进入后台花费太多时间,iOS系统可能直接从内存中删除改应用.正确的做法是,以applicationDidEnterBackground:方法为瓶盖,告诉系统进入后台后还有更多的任务需要完成,从而向系统申请更多的后台时间.在这种方式下,当我们的应用处于后台时,即使

ios实现程序切入后台,实现后台任务 (转自)

1 1,项目需求,是程序home键切入后台,3分钟后退出登陆, 2 3 首先,iOS 会再持续切入后台,给我们5秒钟的时间去处理相关数据,5秒后,程序不会再执行任何代码,处于挂起状态. 4 5 6 7 8 9 - (void)applicationDidEnterBackground:(UIApplication *)application { 10 11 //切入后台 ,申请后台任务时间, 12 13 UIApplication *app = [UIApplication sharedAppl

iOS解决应用进入后台后计时器和位置更新停止的问题

由于iOS系统为"伪后台"运行模式,当按下HOME键时,如程序不做任何操作,应用会有5秒的执行缓冲时间,随机程序被挂起,所有任务终端,包括计时器和位置更新等操作,但程序打开后台模式开关后,部分任务可以再后台执行,如音频,定位,蓝牙,下载,VOIP,即便如此,程序的后台运行最多可以延长594秒(大概是10分钟).不幸的是,程序在声明后台模式后很有可能在app上架时被拒.基于此,我研究出了不用申明后台模式就能让计时器和定位在app进入前台时继续运行的方法. 实现原理如下: 利用iOS的通知

获取系统完成任务所需要的后台时间

有没有一种情况,当软件退出后,你还是需要运行一点东西,或者是需要很长时间来运行的一个代码.此时,就需要向后台申请时间了.但是官司方资料. 根据苹果文档中关于后台执行的描述,任何app都有10分钟左右的后台任务执行时间. 10分钟后,app会被iOS强行挂起. 但是,有5类app允许有“无限的”后台运行时间: 1.  Audio. 2.  Location/GPS. 3.  VoIP. 4.  Newsstand. 5.  Exernal Accessory . 你可以将任何app声明为上述5种类

IOS 7四种后台机制

本文总结了IOS7中的几个后台处理方式,特酷吧摘录部分如下.原始链接:http://mobile.hiapk.com/evaluate/special/131012/1457001.htmlIOS 7中,实际上APP拥有四种后台模式,无论是哪一种后台机制,均需要利用苹果给予的相应后台接口实现.IOS7系统中,开发者可以灵活利用多种后台接口(API)实现更加智能的应用操作.一,无后台仅推送第一种后台方式为传统的无后台操作,仅有苹果推送机制,这种方式出现在iOS 3.x以下的大部分系统版本上.这个方

iOS保持App真后台运行

https://www.jianshu.com/p/d466f2da0d33 在我看来,苹果系统与安卓系统最直观的区别就是后台处理方式了吧,安卓手机一旦开启了很多app放到后台,即使前台什么也不做,就是切换一下系统界面都会觉得卡;苹果手机不论开多少app在后台都感觉很流畅. 这是因为安卓默认处理app为真后台,可以一直在后台处理操作; 而iOS为了让设备尽量省电,减少不必要的开销,保持系统流畅,因而对后台机制采用墓碑式的“假后台”.除了系统官方极少数程序可以真后台,一般开发者开发出来的应用程序后

精通IOS开发-GCD和后台处理

一些生命周期函数的调用时间 打开应用时,调用 applicationWillEnterForeground: applicationDidBecomeActive: 按Home键,调用 applicationWillResignActive: applicationDidEnterBackground: 双击Home键,向上滑动关闭程序,调用 applicationWillTerminate: 状态保存和回复机制参考 http://developer.apple.com/library/ios/

使用 Jenkins 搭建 iOS/Android 持续集成打包平台【转】

背景描述 根据项目需求,现要在团队内部搭建一个统一的打包平台,实现对iOS和Android项目的打包.而且为了方便团队内部的测试包分发,希望在打包完成后能生成一个二维码,体验用户(产品.运营.测试等人员)通过手机扫描二维码后就能直接安装测试包. 该需求具有一定的普遍性,基本上所有开发APP的团队都可能会用到,因此我将整个需求实现的过程整理后形成此文,并且真正地做到了零基础上手,到手即飞.开箱即用,希望能对大家有所帮助. 首先,先给大家展示下平台建设完成后的整体效果: 该平台主要实现的功能有3点: