IOS开发之----详解在IOS后台执行
文一
我从苹果文档中得知,一般的应用在进入后台的时候可以获取一定时间来运行相关任务,也就是说可以在后台运行一小段时间。
还有三种类型的可以运行在后以,
1.音乐
2.location
3.voip
文二
在IOS后台执行是本文要介绍的内容,大多数应用程序进入后台状态不久后转入暂停状态。在这种状态下,应用程序不执行任何代码,并有可能在任意时候从内存中删除。应用程序提供特定的服务,用户可以请求后台执行时间,以提供这些服务。
判断是否支持多线程
- UIDevice* device = [UIDevice currentDevice];
 - BOOL backgroundSupported = NO;
 - if ([device respondsToSelector:@selector(isMultitaskingSupported)])
 - backgroundSupported = device.multitaskingSupported;
 
声明你需要的后台任务
Info.plist中添加UIBackgroundModes键值,它包含一个或多个string的值,包括
audio:在后台提供声音播放功能,包括音频流和播放视频时的声音
location:在后台可以保持用户的位置信息
voip:在后台使用VOIP功能
前面的每个value让系统知道你的应用程序应该在适当的时候被唤醒。例如,一个应用程序,开始播放音乐,然后移动到后台仍然需要执行时间,以填补音频输出缓冲区。添加audio键用来告诉系统框架,需要继续播放音频,并且可以在合适的时间间隔下回调应用程序;如果应用程序不包括此项,任何音频播放在移到后台后将停止运行。
除了添加键值的方法,IOS还提供了两种途径使应用程序在后台工作:
Task completion—应用程序可以向系统申请额外的时间去完成给定的任务
Local notifications—应用程序可以预先安排时间执行local notifications 传递
文三
如何让程序后台播放音乐
http://developer.apple.com/library/ios/#qa/qa1668/_index.html
文四
如果你的应用程序需要后台运行,可以使用以下方法:
1。应用程序可以请求一个有限的时间内完成一些重要任务。
2。应用程序可以声明为支持特定服务需要定期后台执行时间。
3。应用程序可以使用本地生成用户在指定的时间的警报,应用程序正在运行与否的通知。
文五
后台运行被第一次提到
http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html#//apple_ref/doc/uid/TP40009559-SW1
文六
后台运行官方文档
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW3
在IOS后台执行是本文要介绍的内容,大多数应用程序进入后台状态不久后转入暂停状态。在这种状态下,应用程序不执行任何代码,并有可能在任意时候从内存中删除。应用程序提供特定的服务,用户可以请求后台执行时间,以提供这些服务。
判断是否支持多线程
- UIDevice* device = [UIDevice currentDevice];
 - BOOL backgroundSupported = NO;
 - if ([device respondsToSelector:@selector(isMultitaskingSupported)])
 - backgroundSupported = device.multitaskingSupported;
 
声明你需要的后台任务
Info.plist中添加UIBackgroundModes键值,它包含一个或多个string的值,包括
audio:在后台提供声音播放功能,包括音频流和播放视频时的声音
location:在后台可以保持用户的位置信息
voip:在后台使用VOIP功能
前面的每个value让系统知道你的应用程序应该在适当的时候被唤醒。例如,一个应用程序,开始播放音乐,然后移动到后台仍然需要执行时间,以填补音频输出缓冲区。添加audio键用来告诉系统框架,需要继续播放音频,并且可以在合适的时间间隔下回调应用程序;如果应用程序不包括此项,任何音频播放在移到后台后将停止运行。
除了添加键值的方法,IOS还提供了两种途径使应用程序在后台工作:
Task completion—应用程序可以向系统申请额外的时间去完成给定的任务
Local notifications—应用程序可以预先安排时间执行local notifications 传递
实现长时间的后台任务
应用程序可以请求在后台运行以实现特殊的服务。这些应用程序并不连续的运行,但是会被系统框架在合适的时间唤醒,以实现这些服务
1、 追踪用户位置:略
2、在后台播放音频:
添加UIBackgroundModes中audio值,注册后台音频应用。这个值使得应用程序可以在后台使用可听的背景,如音乐播放或者音频流应用。对于支持音频和视频功能的应用程序也可以添加该值以保证可以继续持续的运行流。
当audio值设置后,当你的应用程序进入后台后,系统的多媒体框架会自动阻止它被挂断,但是,如果应用程序停止播放音频或者视频,系统将挂断应用程序。
当你的应用程序在后台时,你可以执行任意的系统音频框架去初始化后台音频。你的应用程序在后台时应该限制自身,使其执行与工作相关的代码,不能执行任何与播放内容无关的任务
由于有多个应用程序支持音频,前台的应用程序始终允许播放音频,后台的应用程序也被允许播放一些音频内容,这取决于audio session object的设置。应用程序应该始终设置它们的audio session object,并小心的处理其他类型的音频相关notifications和中断。详见audio session programming guide。
3、实现VOIP应用:
VOIP程序需要稳定的网络去连接和它相关的服务,这样它才能接到来电和其他相关的数据。系统允许VOIP程序被挂断并提供组件去监听它们的sockets,而不是在任意时候都处于唤醒状态。设置VOIP应用程序如下:
A、 添加UIBackgroundModes中的VOIP键值
B、 为VOIP设置一个应用程序socket
C、在移出后台之前,调用setKeepAliveTimeout:handler:方法去建立一个定期执行的handler,你的应用程序可以运行这个handler来保持服务的连接。
D、 设置你的audio session去处理这种切换
释义:
A、大多数VOIP应用需要设置后台audio 应用去传递音频,因此你应该设置audio 和voip两个键值。
B、为了使应用程序在后台时保持稳定的连接,你必须tag你的主通讯socket专门应用于VOIP,tagging这个socket来告诉系统,它必须在你的应用程序中断时接管这个socket。这个切换本身对于你的应用程序时透明的,当新的数据到达socket的时候,系统会唤醒应用程序,并将socket的控制权返回给应用程序,这样应用程序就可以处理新来的数据。
你只需要tag用于voip服务的socket,这个socket用来接收来电或者其他相关的数据来保持你的VOIP服务的连接。根据收到的信息,这个socket要决定下一步的动作。比如一个来电,你会想弹出一个本地的通知来告知用户;对于其他不是那么关键的数据,你可能会想悄悄的处理这些数据并让系统将应用程序重新中断。
在IOS中,sockets是用流或者更高级的结构,设置一个VOIP的socket,你只需要在通常的设置中添加一个特殊的key来标明这个接口是用于连接VOIP服务的,下表列出了流的接口和设置:
设置流接口用于voip
接口
设置
- NSInputStream 和NSOutputStream
 
对于 Cocoa streams, 使用 setProperty:forKey: 方法添加
- NSStreamNetworkServiceType
 - 属性给
 - stream.
 - 改属性的值设为
 - NSStreamNetworkServiceTypeVoIP.
 - NSURLRequest
 
对于 URL loading system, 使用 setNetworkServiceType:
- method of your NSMutableURLRequest object to set the network service
 - type of the request. The service type should be set to
 - NSURLNetworkServiceTypeVoIP.
 
CFReadStreamRef和CFWriteStreamRef
- For Core Foundation streams, use the CFReadStreamSetProperty or
 - CFWriteStreamSetProperty function to add the kCFStreamNetwork-
 - ServiceType property to the stream. The value for this property should be
 - set to kCFStreamNetworkServiceTypeVoIP.
 
(注意:当设置socket的时候,你需要在你的主信号通道中设置合适的service type key。当设置声道时,不需要设置这个key)
由于,VOIP应用程序需要一直运行以确保收到来电,所以如果程序通过一个非零的exit code退出,系统将自动重启这个应用程序(这种退出方式可以发生在内存压力大时终止程序运行)。尽管如此,中断应用程序会release所有的sockets,包括那个用于连接voip 服务的socket。因此,当程序运行时,它需要一直从头创建socket。
C、为了防止断连,voip程序需要定期被唤醒去检查它的服务。为了容易实现这个行为,IOS通过使用(UIApplication setKeepAliveTimeout:handler:)方法建立一个特殊的句柄。你可以在applicationDidEnterBackground方法中建立该句柄。一旦建立,系统至少会在超时之前调用该句柄一次,来唤醒你的应用程序。
这个keep-alive handler在后台执行,必须尽快的返回参数,它有最多30秒的时间来执行所需的任务,如果这段时间内句柄没有返回,那么系统将终止应用程序。
当你建立了handler之后,确定应用程序所需的最大超时。系统保证会在最大超时之前调用handler,但是这个时间是不确定的,所以你的handler必须在你申明的超时之前做好执行程序的准备。
D、设置audio session,详见Audio Session Programming Guide.
在后台完成有限长度的任务
在被终止之前的任意时间,应用程序会调用beginBackgroundTaskWithExpirationHandler:方法让系统给出额外的时间来完成一些需要在后台长时间执行的任务。(UIApplication的backgroundTimeRemaining属性包含程序运行的总时间)
可以使用task completion去保证那些比较重要但是需要长时间运行的程序不会由于用户切入后台而突然关闭。比如,你可以用这项功能来将用户的信息保存到disk上或者从网络下载一个重要的文件。有两种方式来初始化这样的任务:
1、将长时间运行的重要任务用beginBackgroundTaskWithExpirationHandler:和endBackgroundTask:包装。这样就在程序突然切入后台的时候保护了这些任务不被中断。
2、当你的应用程序委托applicationDidEnterBackground:方法被调用时再启动任务
中的两个方法必须是一一对应的,endBackgroundTask:方法告诉系统任务已经完成,程序在此时可以被终止。由于应用程序只有有限的时间去完成后台任务,你必须在超时或系统将要终止这个程序之前调用这个方法。为了避免被终止,你也可以在一个任务开始的时候提供一个expiration handler和endBackgroundTask:方法。(可以查看backgroundTimeRemaining属性来确定还剩多少时间)。
一个程序可以同时提供多个任务,每当你启动一个任务的时候,beginBackgroundTaskWithExpirationHandler:方法将返回一个独一无二的handler去识别这个任务。你必须在endBackgroundTask:方法中传递相同的handler来终止该任务。
- Listing 4-2 Starting a background task at quit time
 - - (void)applicationDidEnterBackground:(UIApplication *)application
 - {
 - UIApplication* app = [UIApplication sharedApplication];
 - bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
 - [app 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.
 - [app endBackgroundTask:bgTask];
 - bgTask = UIBackgroundTaskInvalid;
 - });
 - }
 
上述例子中,bgTask变量是一个类的成员变量,存储着指向该后台任务标示的指针。
在expriation handler中,可以添加关闭任务所需的代码。尽管如此,加入的代码不能执行太长的时间,当expriation handler被调用的时候,该程序已经非常接近被关闭,所以只有极短的时间来清除状态信息并终止任务。
安排Local Notification的传递
UILocalNotification类提供了一种方法来传递local notifications。和push notifications需要设置remote server不同,local notifications 在程序中安排并在当前的设备上执行。满足如下条件可以使用该能力:
1、一个基于时间的程序,可以在将来特定的时间让程序post 一个alert,比如闹钟
2、一个在后台运行的程序,post 一个local notification去引起用户的注意
为了安排local notification 的传递,需要创建一个UILocalNotification的实例,并设置它,使用UIApplication类方法来安排它。Local notification对象包含了所要传递的类型(sound,alert,或者badge)和时间何时呈现)。UIApplication类方法提供选项去确定是立即传递还是在指定的时间传递。
- Listing 4-3 Scheduling an alarm notification
 - - (void)scheduleAlarmForDate:(NSDate*)theDate
 - {
 - UIApplication* app = [UIApplication sharedApplication];
 - NSArray* oldNotifications = [app scheduledLocalNotifications];
 - // Clear out the old notification before scheduling a new one.
 - if ([oldNotifications count] > 0)
 - [app cancelAllLocalNotifications];
 - // Create a new notification.
 - UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];
 - if (alarm)
 - {
 - alarm.fireDate = theDate;
 - alarm.timeZone = [NSTimeZone defaultTimeZone];
 - alarm.repeatInterval = 0;
 - alarm.soundName = @"alarmsound.caf";
 - alarm.alertBody = @"Time to wake up!";
 - [app scheduleLocalNotification:alarm];
 - }
 - }
 
(可以最多包含128个 local notifications active at any given time, any of which can be configured to repeat at a specified interval.)如果在调用该notification的时候,程序已经处于前台,那么application:didReceiveLocalNotification:方法将取而代之。
小结:关于详解在IOS后台执行的内容介绍完了,希望本文对你有所帮助!
文七
iOS不是真正的多任务系统,在用户按下Home按钮后,所有应用程序都会进入后台状态,并且大部分都会迅速进入暂停状态,应用程序的所有工作内存都在RAM中,在暂停时它完全不执行。因此,切换回这样的应用程序非常快。但是如果系统需要更多的内存给当前处于活动状态的应用程序,就有可能终结暂停状态的应用程序,它们的内存也将被释放。
一方面,应用程序在进入后台状态时,需要释放一些资源,使自身的暂停快照更小,从而减少从RAM中清除的风险,另一方面,为了避免被终结而丢失用户的数据,需要在用户离开时保存他们的进度信息,这些工作,需要在5秒钟内完成,不然会被系统认定有异常被强制退出。可能通过接收应用程序发送的通知(UIApplicationDidEnterBackgroundNotification)来触发处理,如果在处理代码中加上下面这条语句则必然会导致异常退出:
可以通过一种方法来请求更多后台时间来避免此问题。假设接收通知而触发的处理方法是applicationDidEnterBackground:
- -(void)applicationDidEnterBackground{
 - NSLog(@"%@",NSStringFromSelector(_cmd));
 - //得到当前应用程序的UIApplication对象
 - UIApplication *app = [UIApplication sharedApplication];
 - //一个后台任务标识符
 - UIBackgroundTaskIdentifier taskID;
 - taskID = [app beginBackgroundTaskWithExpirationHandler:^{
 - //如果系统觉得我们还是运行了太久,将执行这个程序块,并停止运行应用程序
 - [app endBackgroundTask:taskID];
 - }];
 - //UIBackgroundTaskInvalid表示系统没有为我们提供额外的时候
 - if (taskID == UIBackgroundTaskInvalid) {
 - NSLog(@"Failed to start background task!");
 - return;
 - }
 - NSLog(@"Starting background task with %f seconds remaining", app.backgroundTimeRemaining);
 - [NSThread sleepForTimeInterval:10];
 - NSLog(@"Finishing background task with %f seconds remaining",app.backgroundTimeRemaining);
 - //告诉系统我们完成了
 - [app endBackgroundTask:taskID];
 - }
 - 转载地址:http://blog.sina.com.cn/s/blog_71715bf80101d4z0.html
 
IOS开发之----详解在IOS后台执行的更多相关文章
- iOS开发——Block详解
		
iOS开发--Block详解 1. Block是什么 代码块 匿名函数 闭包--能够读取其他函数内部变量的函数 函数变量 实现基于指针和函数指针 实现回调的机制 Block是一个非常有特色的语法,它可 ...
 - iOS开发:详解Objective-C runTime
		
Objective-C总Runtime的那点事儿(一)消息机制 最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎 ...
 - iOS开发-Runtime详解
		
iOS开发-Runtime详解 简介 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的.比如: [recei ...
 - iOS开发--Bison详解连连支付集成简书
		
"最近由于公司项目需要集成连连支付,文档写的不是很清楚,遇到了一些坑,因此记录一下,希望能帮到有需要的人." 前面简单的集成没有遇到什么坑,在此整理一下官方的集成文档,具体步骤如下 ...
 - iOS开发——MVC详解&Swift+OC
		
MVC 设计模式 这两天认真研究了一下MVC设计模式,在iOS开发中这个算是重点中的重点了,如果对MVC模式不理解或者说不会用,那么你iOS肯定学不好,或者写不出好的东西,当然本人目前也在学习中,不过 ...
 - iOS开发-NSURLSession详解
		
Core Foundation中NSURLConnection在2003年伴随着Safari浏览器的发行,诞生的时间比较久远,iOS升级比较快,AFNetWorking在3.0版本删除了所有基于NSU ...
 - iOS开发之详解正则表达式
		
本文由Charles翻自raywenderlich原文:NSRegularExpression Tutorial: Getting Started更新提示:本教程被James Frost更新到了iOS ...
 - iOS开发-Runtime详解(简书)
		
简介 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的.比如: [receiver message]; // ...
 - iOS开发CAAnimation详解
		
Core Animation,即为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍.也就是说,使用少量的代码就可以实现非常强大的功能.Core Anima ...
 
随机推荐
- 动态规划专题 01背包问题详解 HDU 2546 饭卡
			
我以此题为例,详细分析01背包问题,希望该题能够为大家对01背包问题的理解有所帮助,对这篇博文有什么问题可以向我提问,一同进步^_^ 饭卡 Time Limit: 5000/1000 MS (Java ...
 - docker容器的参数如何指定配额
			
docker容器的参数如何指定配额 1. 内存 现在让我看下内存限制. 第一件事需要注意的是,默认一个容器可以使用主机上的所有内存. 如果你想为容器中的所有进程限制内存,使用docker run命令的 ...
 - 利用vs自带工具分析程序性能
			
测试程序写好后可以通过VS2010分析菜单里选择启用性能向导 选择CPU采样后就选择需要分析的项目 测试项目选择完成后就可以运行分析,结束分析后VS2010会提供个详细报告文档 从分析结果来看GetC ...
 - Coloring Brackets
			
题意: 给一匹配的括号序列,要求每对括号恰有一个被染成蓝或红色,要求相邻的括号不同色,求方案数. 解法: 类比树的hash将括号序列转化为一棵树,树上子节点之间不得出现冲突, 子节点和父节点不得出现冲 ...
 - ThinkPHP3.2.3中,配置文件里配置项的读取
			
在ThinkPHP3.2.3的版本中,配置项的读取,有两种情况. 是在PHP文件或者在PHP代码中的读取方法为C函数,例如:C('配置项的名称'); 在HTML模板中的读取方法为,例如{$Think. ...
 - 一个C#开发者重温C++的心路历程
			
不知道为什么,似乎很多人理解跑偏了,在这里我要说明一下. 首先,我并没有对C++语言有偏见,我只是单纯的在学习时,在理解时,对C++语言进行一些吐槽,我相信,很多学习C++的人,也会有类似的吐槽. 其 ...
 - 玲珑OJ1088【蜜汁尺取】
			
前言(膜法): 早上10点多开始膜的,然后到中午交了一发,感觉膜法不对啊!然后就兴起小窗了一发管理员,然后管理员给我发了in,out数据...可是太大并没有什么可取性... 还是自己试,然后发现自己搞 ...
 - lightoj 1078【同余定理】
			
题意: 给你一个n和一个数 digit ,问你最少需要多少个 digit 使得整除于n; 思路: 同余定理(a+b)%n=(a%n+b%n)%n; (m%n+m%n*10+m%n*100+m%n*10 ...
 - 【IDEA】关于 IDEA 中新建 web 项目的 webapp 文件夹没有小蓝点 ,启动服务,访问不到解决方案
			
问题描述: 新建的 maven 的 Module 项目,webapp 文件夹也是在创建完项目后手动添加的,出现了 webapp 文件夹不能被识别的情况. 解决方案: 第一步: 选中项目按 F4 键, ...
 - Bootstrap Table 从新InsertRow 刷新表格 数据的问题处理方案
			
1.第一步获取数据源 var rows = { //要插入的数据,这里要和table列名一致SkuCode: data.rows[i].SkuCode,BarCode: data.rows[i].Ba ...