http://www.cocoachina.com/applenews/devnews/2012/1212/5313.html

我们知道iOS开启后台任务后可以获得最多600秒的执行时间,而一些需要在后台下载或者与服务器保持连接的App是如何突破600秒的限制的呢?像网易公开课就可以在后台持续下载,优酷也可以在后台持续缓存,这是怎么做到的呢?一般来说,要实现iOS长时间后台运行,需要声明VOIP、Audio或GPS。
 
Audiosession
 
实现方法很简单,就是在后台一直播放一个无声的音乐文件,这样就相当于声明了Audio,就可以轻松突破600秒的限制了。
 
通过播放“静默”音让程序在后台执行的做法(即在audiounit回调函数中使用kAudioUnitRenderAction_OutputIsSilence标志位),虽然确实可以实现后台执行,但实践中限制很多。最大的问题就在于程序的audiosession不能被打断。当程序执行在后台时,只要另一个程序使用kAudioSessionCategory_RecordAndPlay(比如Skype)或者kAudioSessionCategory_SoloAmbientSound(印象中使用这个session的不多),那么本程序就会被立即打断。
 
打断本身不是问题,但当播放程序被打断时,唯一能够获得的只有处理audiosessioninterruption的很短一段时间。我的实验测试大概是3到5秒,但因为程序随后立即暂停,无法挂调试器,所以很难准确估计,然后程序就会被立即转入休眠状态。这点时间和applicationDidEnterBackground回调函数所用的时间大体相当,但是因为这个打断中间还伴随一个播音的回调动作,程序结构不是很好组织,在很多情况下是不够做现场保存工作的。
 
不推荐播放“静默”音的另一个问题它的恢复播放需要的场景非常麻烦。比如当一个iOS程序在后台被VOIP唤醒时,它是不能直接获得audiounit重新开始播音的。如果此时调用AudioOutputUnitStart(),会返回一个错误码,哪怕前台没有任何一个程序在运行也是如此。此时你不可能让程序重新进入稳定运行状态。有些没经验的程序员喜欢利用audiosessioninterruptionhandler做所谓的自动播放恢复,但他们其实都没有注意到audiosessioninterruption的状态恢复回调并不会保证被调用。目前实测能自动恢复调用的,大概也就只有内建的电话拨号程序,以及一些非常特殊的场景(比如你用一个MP3播放器打断audiosession,然后杀掉MP3播放器进程,然后把被打断的程序重新置回前台)。这样经常导致的结果,就是你开心地发现程序没问题,然后在放进生产环境中发现各种时不时的崩溃或启动失败。
 
VOIPsocket
 
VOIPSocket可以在后台运行。当程序进入后台时,事实上整个程序被暂停运行,但VOIPsocket因为受系统控制而不在此列。我的观察是,每次有新的数据来临时,程序会被唤醒并执行大约几秒钟,然后再次进入休眠。Stackoverflow上的说法是10秒钟,但我不确定,可能是我的试验不够精确。

实现iOS长时间后台的两种方法:Audiosession和VOIP的更多相关文章

  1. 实现iOS长时间后台的两种方法:Audiosession和VOIP(转)

    分类: Iphone2013-01-24 14:03 986人阅读 评论(0) 收藏 举报 我们知道iOS开启后台任务后可以获得最多600秒的执行时间,而一些需要在后台下载或者与服务器保持连接的App ...

  2. AE工程渲染的时间缓慢,两种方法减少对AE工程渲染的时间!

    AE工程渲染的时间缓慢,两种方法减少对AE工程渲染的时间!3秒的片头,渲染时间竟然要花1个多小时,很多新手都产生过这样的疑问?是哪里不对吗?如何才能减少渲染视频的时间?且听我一一道来.主要原因是:工程 ...

  3. iOS 创建单例的两种方法

    创建一个单例很多办法.我先列举一个苹果官方文档中的写法. [cpp] view plaincopy static AccountManager *DefaultManager = nil; + (Ac ...

  4. ios 设置屏幕方向的两种方法

    第一种:通过人为的办法改变view.transform的属性. 具体办法: view.transform一般是View的旋转,拉伸移动等属性,类似view.layer.transform,区别在于Vi ...

  5. 解决DataSnap支持的Tcp长连接数受限的两种方法

    如何解决DataSnap支持的Tcp长连接数受限的问题? 方案一: 采用代理服务器方式,基本流程为: 1.客户先连接代理服务器:2.获取可用的服务器IP和端口:3.关闭与代理服务器之间的连接:4.建立 ...

  6. Longest Palindromic Substring (最长回文字符串)——两种方法还没看,仍需认真看看

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  7. iOS UIimage初始化时的两种方法

    第一种方式:UIImage *image = [UIImage imageNamed:@"image"]; 使用这种方式,第一次读取的时候,先把这个图片存到缓存里,下次再使用时直接 ...

  8. iOS截取视频缩略图的两种方法

    前言: 看完了使用MPMoviePlayerController播放在线视频,在实际应用中有时候须要获取视频的缩略图,我们来看看怎样截取指定时间内的视频缩略图. 一  使用MPMoviePlayerC ...

  9. IOS创建单例的两种方法

    1.0  苹果官方写法:  static AccountManager *DefaultManager = nil; + (AccountManager *)defaultManager { if ( ...

随机推荐

  1. How to fix Eclipse Tomcat startup timeout in 45 seconds?

    命题:怎么修复 Eclipse 里启动 Tomcat 时, 默认启动超时时间为 45 秒的问题? 在 Eclipse 的 J2EE 项目里启动 Tomcat 来调试 Servlet 之类的,断点以后, ...

  2. jquery easyui:tab自动加载第一个tab内容

    $('#resourceTabs').tabs('unselect', 0);$('#resourceTabs').tabs('select', 0);

  3. SQL Server 连接池 (ADO.NET) MSDN

    连接到数据库服务器通常由几个需要很长时间的步骤组成. 必须建立物理通道(例如套接字或命名管道),必须与服务器进行初次握手,必须分析连接字符串信息,必须由服务器对连接进行身份验证,必须运行检查以便在当前 ...

  4. Java继承概述

    继承概述 : 父类(超类,基类): 子类(派生类): extends 只能继承一个类,Java不支持多重继承: 子类继承父类之后,子类可以调用父类的属性和方法, 也可以重写父类的属性和方法,还可以增加 ...

  5. 浅谈js设计模式 — 命令模式

    命令模式最常见的应用场景是:有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么.此时希望用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦 ...

  6. Tomcat不同版本所对应的Servlet/JSP规范

    上午在别人机器上做演示,写好 Servlet居然访问不了.后来回想叻下,觉得应该是Tomcat版本不一致的问题,我用的是Tomcat 7.0建的Project,他们大多数都是用的6.0的版本.回来又仔 ...

  7. IOS使用批处理打包

    一.注意 1.允许xcode访问钥匙串 首先使用xcode提供的打包工具打包,看到如下提示后,输入用户密码后点击“始终允许”后再次打包即可. 选择“Generic IOS Device”然后单击Pro ...

  8. 如何让Ubuntu 12.04 LTS更炫更具吸引力

    Ubuntu 12.04 LTS震撼发布   适逢七周岁生日之际,Ubuntu正式推出了第四个LTS长期支持版本,开发代号Precise Pangolin的Ubuntu 12.04在2012年4月26 ...

  9. 交叉验证(Cross Validation)简介

    参考    交叉验证      交叉验证 (Cross Validation)刘建平 一.训练集 vs. 测试集 在模式识别(pattern recognition)与机器学习(machine lea ...

  10. HDU 4725 The Shortest Path in Nya Graph (最短路)

    The Shortest Path in Nya Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...