iOS实现长时间后台的两种方法:Audio session和VOIP socket

十二月 04

我们知道 iOS 开启后台任务后可以获得最多 600 秒的执行时间,而一些需要在后台下载或者与服务器保持连接的 App 是如何突破 600 秒的限制的呢?像网易公开课就可以在后台持续下载,优酷也可以在后台持续缓存,这是怎么做到的呢?一般来说,要实现 iOS 长时间后台运行,需要声明 VOIP、Audio 或 GPS。

Audio session

实现方法很简单,就是在后台一直播放一个无声的音乐文件,这样就相当于声明了 Audio,就可以轻松突破 600 秒的限制了。

通过播放“静默”音让程序在后台执行的做法(即在 audio unit 回调函数中使用 kAudioUnitRenderAction_OutputIsSilence 标志位),虽然确实可以实现后台执行,但实践中限制很多。最大的问题就在于程序的 audio session 不能被打断。当程序执行在后台时,只要另一个程序使用 kAudioSessionCategory_RecordAndPlay (比如 Skype)或者 kAudioSessionCategory_SoloAmbientSound(印象中使用这个session 的不多),那么本程序就会被立即打断。

打断本身不是问题,但当播放程序被打断时,唯一能够获得的只有处理 audio session interruption 的很短一段时间。我的实验测试大概是 3 到 5 秒,但因为程序随后立即暂停,无法挂调试器,所以很难准确估计,然后程序就会被立即转入休眠状态。这点时间和 applicationDidEnterBackground 回调函数所用的时间大体相当,但是因为这个打断中间还伴随一个播音的回调动作,程序结构不是很好组织,在很多情况下是不够做现场保存工作的。

不推荐播放“静默”音的另一个问题它的恢复播放需要的场景非常麻烦。比如当一个 iOS 程序在后台被 VOIP 唤醒时,它是不能直接获得 audio unit 重新开始播音的。如果此时调用 AudioOutputUnitStart() ,会返回一个错误码,哪怕前台没有任何一个程序在运行也是如此。此时你不可能让程序重新进入稳定运行状态。有些没经验的程序员喜欢利用 audio session interruption handler 做所谓的自动播放恢复,但他们其实都没有注意到 audio session interruption 的状态恢复回调并不会保证被调用。目前实测能自动恢复调用的,大概也就只有内建的电话拨号程序,以及一些非常特殊的场景(比如你用一个 MP3 播放器打断 audio session,然后杀掉 MP3 播放器进程,然后把被打断的程序重新置回前台)。这样经常导致的结果,就是你开心地发现程序没问题,然后在放进生产环境中发现各种时不时的崩溃或启动失败。

VOIP socket

VOIP  Socket 可以在后台运行。当程序进入后台时,事实上整个程序被暂停运行,但 VOIP socket 因为受系统控制而不在此列。我的观察是,每次有新的数据来临时,程序会被唤醒并执行大约几秒钟,然后再次进入休眠。Stackoverflow 上的说法是 10 秒钟,但我不确定,可能是我的试验不够精确。

IOS Audio session的更多相关文章

  1. AVAudioSession(1):iOS Audio Session 概览

    本文转自:AVAudioSession(1):iOS Audio Session 概览 | www.samirchen.com 本文内容主要来源于 Audio Session Programming ...

  2. AVAudioSession(2):定义一个 Audio Session

    本文转自:AVAudioSession(2):定义一个 Audio Session | www.samirchen.com 本文内容主要来源于 Defining an Audio Session. A ...

  3. audio session config

    #pragma mark - #pragma mark - audio session config - (void)setAudioSessionConfig { NSError *error; A ...

  4. AVAudioSession(3):定制 Audio Session 的 Category

    本文转自:AVAudioSession(3):定制 Audio Session 的 Category | www.samirchen.com 本文内容主要来源于 Working with Catego ...

  5. ios audio不能自动播放

    今天做了一个简单的落地页项目,就是类似于手机微信上经常看到的滑动效果.因为公司要求需要自己开发,所以我就用swiper+swiper.animate开发,开发速度很快,只不过最后音乐哪里出现了一点小b ...

  6. ios audio不能够正常播放

    ios中audio不能直接通过audio.play()播放,需要用户在click事件或者touch事件中执行audio.play()才能播放. ajax回调中audio.play()音乐不能正常播放. ...

  7. Audio Session Interruption

    近期处理了一个挂断电话后,莫名手机开始播放音乐的Bug. 所以顺便在这总结一下,对于IOS的AudioSession中断的几种处理情况. 一.通过C语言的init方法配置interruptionl回调 ...

  8. iOS audio不支持循环播放

    解决办法:监听播放完成事件(注意点,audio标签不能设置循环播放,去除标签 loop="loop"或者 loop="false",不然不走播放完成事件) $( ...

  9. iOS中session和cookie的使用

    获取session的方法: #pragma mark - 获取session -(NSString *)getsession{ NSHTTPCookieStorage *cookieStorage = ...

随机推荐

  1. vue UI 框架

    (1)Element 饿了么 vue 2.0后台UI框架 (Star:18382) https://github.com/ElemeFE/element (1-1)Vuetify   最新的ui 框架 ...

  2. 安装Domino分区服务器

    主要是修改修改notes.ini文件 •所有分区服务器使用同一个 IP 地址     指定不同端口 ,端口映射服务器使用端口号1352.建议对其他分区服务器使用端口号 1352以后的TCPIP_Tcp ...

  3. CSU 1046 追杀

    Description 在一个8行9列的国际象棋棋盘上,有一名骑士在追杀对方的国王.该骑士每秒跨越一个2*3的区域,如下图所示. 而对方的国王慌忙落逃,他先沿着右下斜线方向一直跑,遇到边界以后会沿着光 ...

  4. GDSOI2019划水记

    Day -9 北京集训结束,飞回广州浪两天后回校. Day -2 回家休整,打麻将技术进一步提高. Day 0 前往佛山入住酒店,论被人用大床房换双人房是什么体验??(一个人住真的舒服) 待在房间背模 ...

  5. ios学习之block初探

    1. block概念 block是ios4.0+和Mac osX 10.6以后引进的对C语言的拓展,用来实现匿名函数的特性.所谓匿名函数,也称闭包函数.即同意创建一个暂时的没有指定名称的函数. 最经经 ...

  6. RelativeLayout-代码中成员控件width height

    今天需要在代码中动态的设置一个textview的width跟height属性,记录下来. textview在xml中的布局如下 <RelativeLayout android:layout_wi ...

  7. Arrays.asList()方法的限制

    Arrays.asList()方法的限制是他对所产生的List类型做出了最理想的假设 package example; import java.util.Arrays; import java.uti ...

  8. Windows(x86,64bit)升级MySQL 5.7.17免安装版的详细教程

    MySQL需要升级到5.5.3以上版本才支持Laravel 5.4默认的utf8mb64字符编码.因此就把MySQL升级了一下,期间还是遇到些小问题,记录一下以供参考. 升级准备 备份之前MySql目 ...

  9. PatentTips - Supporting address translation in a virtual machine environment

    BACKGROUND A conventional virtual-machine monitor (VMM) typically runs on a computer and presents to ...

  10. vanzo-代码共享平台地址

    网页编辑.烧录代码 1.登录服务器 192.168.1.52 2.选择modules 3.选择builder 4.在 Project Name:填入要拉的项目名 选择版本:user,eng,userd ...