1、iOS的“伪后台”程序程序员
首先,先了解一下iOS 中所谓的「后台进程」究竟是怎么回事吧?web
Let me be as clear as I can be: the iOS multitasking bar does not contain "a list of all running apps". It contains "a list of recently used apps". The user never has to manage background tasks on iOS.数组
首先咱们得搞清楚的是,iOS 中所谓的「后台驻留」并非指「执行中的程序」,而是「最近使用过的程序」,也能够瞧瞧Apple 的知识库文章怎么写的:
按两下主画面按钮后,显示的是「最近用过的应用程序」,因此别把它想成Mac OS X 中的Command + Tab 键所显示的切换程序列;你能够试试看将iPhone 关机再开机,而后按两下Home 键,应该会发现先前那些程式仍是出如今那里,由于它实际上是你最近使用过的程序使用记录,或像是浏览器中的浏览记录)。
若是你一个一个去清除 "后台驻留" 的程序,就像是一笔一笔删除浏览记录中的项目同样,是没有太大意义的(除非你不想让其余人看到你曾经用过什么程式,或者想杀时间、太无聊了),也不会对电力或记忆体有什么帮助。
iOS 的多任务处理实际上是很聪明的,系统会自动停止在背景执行的程序,在有须要时,也会将被停止的程式suspended(注:"停止的程式"不是指关闭程序,而是指由前台转向后台的程序,程序在后台并不真正运行,不要和关闭程序混淆了) 从内存中移除。所以,iOS 装置的使用者根本就不须要担忧怎么管理这些执行中或不在执行中的程序,尽管放心用、轻松玩就是了!浏览器
通常说来,全部程式进入背景后都还有5 秒的执行缓冲时间,有些程序能够要求延长到10 分钟(这些固然是由开发人员在设计与提交程式时决定和声明);安全
所以,在你按下Home 键后,原本的程式就会退到背景,若是它有额外的背景执行做业,超过10 分钟仍是会被iOS 停止;因此,仍是别担忧了!服务器
可是,也有例外状况,某些特殊类型的程式是被允许在背景中持续执行的,像是会持续在背景播放音乐的程序、GPS 程序、VOIP 程序、Newsstand 以及周边配件附属的程序,不过只要这些程序再也不执行动做,就会变成停止的程式,像是音乐拨完了、杂志下载完了... 所以,使用者其实也不必太过留意这些程序。
you do not have to manage background tasks on iOS. The system handles almost every case for you and well written audio, GPS, VOIP, Newsstand and accessory apps will handle the rest.网络
2、iOS的“多任务”发展史架构
自从出现了操做系统以来,就没有过所谓真正的“多任务”。所谓多任务,无非是CPU速度够快而足以支撑极短期内在多个进程内动做罢了。而所谓的“单任务”,无非是只能让当前任务独享资源罢了。app
简单来讲,iOS 4 APP类型能够分为三种:框架
1. 保存现场。
即:按下Home键10秒内直接杀死进程,并释放内存。通常说来,全部程序进入背景后都还有5 秒的执行缓冲时间,有些程序能够要求延长到10 分钟(这些固然是由开发人员在设计与提交程式时决定和声明);所以,在你按下Home 键后,原本的程式就会退到背景,若是它有额外的背景执行做业,超过10 分钟仍是会被iOS 停止。
2. iOS支持的“多任务”。
即:按下Home键转入多任务状态,保留在内存中,但只能系统容许的动做:好比GPS,好比VoIP,好比Streaming Music等等。
3. 真正的桌面级别的多任务。
即:只有Safari/Mail才是真正的多任务,苹果嫡系大都都不是。这个级别的app在后台是没有任何限制动做。(对于无限制动做的程序,一是会在用户无察觉的状况下耗光电力,二是会有安全上面的问题)。
注意:对于上述三种级别,后两种会占用内存的APP,也会在任意时间从内存中被砍掉,取决于你是否动用了其它app而致使内存不足。真正不会被砍掉的后台,只有苹果那个通知系统。
其实能够回顾一下iOS是怎么一步步引入如今这个机制的:
1. 刚出生,什么都没有,单纯的单任务。
2. iPhone OS 3.0,引入通知架构。几乎当年所有机型可用;Android晚了一年,2.2才有此功能,到这个时候相信才有90%上下机器用上。
3. iOS 4.0+,引入有限制的后台多任务。
搞这么复杂干吗?直接像Android一出生那样全部app一个小虚拟机,无任何限制动做,让根本没有内存管理经验和资源消耗概念的全世界最大民工群Java程序员们写的app任意地跑着吧!
答案只有两个:电力,安全。安全不说,如何在保持多任务优点的同时,避免消耗过多电力,苹果花了不少心思;而不是像webOS/Android同样,简单粗暴桌面级的多任务。iPhone 4甚至在硬件上面也下了苦功,利用3D层叠技术组装A4芯片,内部元件高度集成,并把天线移至体表,增长内部电池空间。
其实至iPhone OS 3,已经足够应付大部分应用了。用户根本无从知道app的实际运行状态,保存现场让app看起来不像是刚打开同样,通知系统又能够在后台默默推送消息。事实上,当前95% iOS APP依旧只有“保存现场 + 通知系统”这样的组合,好比不少twitter客户端,大部分人根本不会注意到它不是真正意义上的“多任务”。很震撼的事实,但确实95%的应用场景根本不须要所谓真正的“多任务”。
可是时代在变。真正须要多任务的东西出现了:电台要stream,IM要stream,GPS要stream,多任务必须提上日程。iOS 4加进了,WP7刚刚加进了,Android/webOS打一出生就有。从本质来讲,iOS/WP7/Android/webOS跑在内存中的后台程序,惟一的区别就是,iOS/WP7限制了它能够作的事(这就是为何它们一出生都没有多任务的缘由,这个架构很复杂,不是几百行中文字能够说明白的),而Android/webOS没有;从技术上面来讲,iOS/WP7/webOS三者架构至关,Android独立门户。
因而很好笑,有无限制,成了真“多任务”和伪“多任务”的区别;然后者架构更复杂,能够套用一句“吃力不讨好”。
为何要作吃力不讨好的事?答案依旧在上面,电力和安全。固然你能够说iPhone电力也没好到哪里去,安全也就通常般嘛。暂且抛掉这两样不谈,实际看看iOS有限制后台app,和Android彻底无限制后台app有什么不一样:
相信我,最终你会发现iOS上最使人诟病的app,是那些不支持标准协议的软件平台商们,好比腾讯。由于iOS后台容许的动做,已经覆盖了所有大大小小的通讯开源协议。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
3、IOS长时间后台运行的实现代码
一、检查设备是否支持多任务
Apple出于性能的考虑,并非全部的iOS设备升级到iOS4之后都支持多任务,好比iPhone 3G。若是你的应用在没有多任务特性时会出问题,为了保持应用的健壮性,你应该对此进行判断并处理。你能够经过调用UIDevice对象的multitaskingSupported属性来获取当前设备是否支持多任务。
一般,当用户按一下Home键,当前应用就会被进入后台,应用处在后台运行状态一小段时间后,就会进入挂起(suspend)状态,此时应用不会再执行任何代码。若是系统在运行其余应用时内存资源不足,这个挂起的应用甚至有可能被系统退出,释放内存以供活动的应用使用。只有当用户再次运行此应用,应用才会从挂起状态唤醒,代码得以继续执行。这就是iOS4带来的基本的多任务特性,这个特性是通常应用默认支持的,就是说你的应用不须要任何修改就能支持基本多任务特性。二、基本多任务特性
既然是多任务你应该会在应用进入后台时作一些处理,好比暂停一些界面的定时刷新或网络请求。同时,或者你会在程序进入前台时执行一些恢复操做。在你的应用的application delegate里有2个消息用于处理这些消息:
也许你须要更多的多任务特性,好比后台播放音乐或者是后台进行GPS跟踪。这会是下面介绍的内容。固然你也许不会都在application delegate处理全部的事情。若是你要在其余对象中处理,那么你就须要注册系统通知了,这两个通知分别是UIApplicationDidEnterBackgroundNotification和UIApplicationWillEnterForegroundNotification。
三、声明你须要的后台任务
在Info.plist中添加UIBackgroundModes键值,它包含一个或多个string的值,包括:
audio:在后台提供声音播放功能,包括音频流和播放视频时的声音
location:在后台能够保持用户的位置信息
voip:在后台使用VOIP功能
前面的每一个value让系统知道你的应用程序应该在适当的时候被唤醒。例如,一个应用程序,开始播放音乐,而后移动到后台仍然须要执行时间,以填补音频输出缓冲区。添加audio键用来告诉系统框架,须要继续播放音频,而且能够在合适的时间间隔下回调应用程序;若是应用程序不包括此项,任何音频播放在移到后台后将中止运行。
除了添加键值的方法,IOS还提供了两种途径使应用程序在后台工做:
Task completion—应用程序能够向系统申请额外的时间去完成给定的任务
Local notifications—应用程序能够预先安排时间执行local notifications 传递
四、后台播放音乐
一般,通常应用在进入后台时,任何声音就将会中止。这也许不是咱们所想要的。要想让本身的应用支持后台播放,首先要修改应用的Info.plist文件,你须要在Info.plist文件中添加UIBackgroundModes字段,该字段的值是应用支持的全部后台模式,是一个数值类型。目前此数组能够包含“audio”、“location”和“voip”这三个字符串常量,若是要支持后台音乐播放,你就须要包含“audio”,其他两个会将在后面讲到。
同时,你也应该设置一下应用程序的Audio Sesstion。这个是必需的,若是不设置Audio Sesstion,应用就可能进入后台时Audio Sesstion失活而中止播放。通常须要这么设置就能够了:
五、后台GPS跟踪
和后台播放音乐相似,若要支持后台GPS跟踪,你就须要在Info.plist文件中UIBackgroundModes字段对应的数组中增长“location”字符串。
六、后台voip支持
因为voip应用须要一个长链接到服务器,为了让这类应用能正常工做,iOS中加入后台voip支持特性。为支持这一特性,须要在Info.plist文件中UIBackgroundModes字段对应的数组中增长“voip”字符串。
此外你仍然须要配置一下你的网络链接,以便支持后台链接。iOS提供的网络链接库有几种,下面一一说明:
a、若是你使用的是NSStream,如NSInputStream或NSOutputStream,须要调用setProperty:forKey:将Key为NSStreamNetworkServiceType的value设置为
NSStreamNetworkServiceTypeVoIP;
b、若是你使用NSURLRequest,须要调用setNetworkServiceType:将网络类型设置为NSURLNetworkServiceTypeVoIP;
c、若是你使用CFStream,如CFReadStreamRef或CFWriteStreamRef,须要调用CFReadStreamSetProperty或CFWriteStreamSetProperty将
kCFStreamNetworkServiceType属性设置为kCFStreamNetworkServiceTypeVoIP。