在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
 
接口

设置

  1. NSInputStream 和NSOutputStream

对于 Cocoa streams, 使用 setProperty:forKey: 方法添加

  1. NSStreamNetworkServiceType
  2. 属性给
  3. stream.
  4. 改属性的值设为
  5. NSStreamNetworkServiceTypeVoIP.
  6. NSURLRequest

对于 URL loading system, 使用 setNetworkServiceType:

  1. method of your NSMutableURLRequest object to set the network service
  2. type of the request. The service type should be set to
  3. NSURLNetworkServiceTypeVoIP.

CFReadStreamRef和CFWriteStreamRef

  1. For Core Foundation streams, use the CFReadStreamSetProperty or
  2. CFWriteStreamSetProperty function to add the kCFStreamNetwork-
  3. ServiceType property to the stream. The value for this property should be
  4. 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 - 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,
), ^{
// 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 - 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] > )
[app cancelAllLocalNotifications];
// Create a new notification.
UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];
if (alarm)
{
alarm.fireDate = theDate;
alarm.timeZone = [NSTimeZone defaultTimeZone];
alarm.repeatInterval = ;
alarm.soundName = @"alarmsound.caf";
alarm.alertBody = @"Time to wake up!";
[app scheduleLocalNotification:alarm];
}
}

IOS 后台执行的更多相关文章

  1. IOS后台执行

    大多数应用程序进入后台状态不久后转入暂停状态.在这种状态下,应用程序不执行任何代码,并有可能在任意时候从内存中删除.应用程序提供特定的服务,用户可以请求后台执行时间,以提供这些服务. 判断是否支持多线 ...

  2. IOS开发之----详解在IOS后台执行

    文一 我从苹果文档中得知,一般的应用在进入后台的时候可以获取一定时间来运行相关任务,也就是说可以在后台运行一小段时间. 还有三种类型的可以运行在后以,1.音乐2.location 3.voip 文二 ...

  3. IOS后台执行机制 与 动作

    当用户按下"Home"键或者系统启动另外一个应用时,前台foreground应用首先切换到Inactive状态,然后切换到Background状态.此转换将会导致先后调用应用代理的 ...

  4. IOS 后台执行 播放音乐

    iOS 4開始引入的multitask.我们能够实现像ipod程序那样在后台播放音频了. 假设音频操作是用苹果官方的AVFoundation.framework实现.像用AvAudioPlayer.A ...

  5. iOS后台运行

    http://www.cocoachina.com/bbs/read.php?tid=149564 文一 我从苹果文档中得知,一般的应用在进入后台的时候可以获取一定时间来运行相关任务,也就是说可以在后 ...

  6. iOS 后台运行实现 --备用

    文一 我从苹果文档中得知,一般的应用在进入后台的时候可以获取一定时间来运行相关任务,也就是说可以在后台运行一小段时间. 还有三种类型的可以运行在后以,1.音乐2.location 3.voip 文二 ...

  7. IOS的后台执行

    写在前面给大家推荐一个不错的站点  www.joblai.com 本文章由央广传媒开发部 冯宝瑞整理.哈哈 http://www.cocoachina.com/bbs/read.php? tid=14 ...

  8. iOS 项目一直在后台执行

    我后来是这么解决不知道行不行,能够长期的在后台执行 首先我在xx-info.plist 里的 "Required background modes" 里增加"App pr ...

  9. iOS 后台处理

    iOS 后台处理的常见用途 1.进入后台时候删除资源:应用处于挂起状态的时候所占用的资源越少,该应用被iOS终止的风险就越低.通过从内存中清理那些易于重新创建的资源,可以增加应用驻留内存的机会,因此可 ...

随机推荐

  1. SQL 32位还原位64位出现3154错误

    1:首先检查新建数据库的路径是否正确. 2:勾选覆盖原有数据库. 3:新建查询,选择master.然后新建查询中进行如下直接对bak文件的操作. RESTORE DATABASE TestFROM D ...

  2. Linux - wc统计文件行数、单词数或字节数

    一 wc简单介绍 wc命令用来打印文件的文本行数.单词数.字节数等(print the number of newlines, words, and bytes in files).在Windows的 ...

  3. cocos2dx实例开发之flappybird(入门版)

    cocos2dx社区里有个系列博客完整地复制原版flappybird的全部特性.只是那个代码写得比較复杂,新手学习起来有点捉摸不透,这里我写了个简单的版本号.演演示样例如以下: watermark/2 ...

  4. IOS中类和对象还有,nil/Nil/NULL的区别

    转自:http://blog.sina.com.cn/s/blog_5fb39f910101akm1.html 类与对象的概念 类是对同一类事物高度的抽象,类中定义了这一类对象所应具有的静态属性(属性 ...

  5. Ubuntu下安装FTP服务及使用(VSFTPD详细设置)(二)

    vsftpd 作为一个主打安全的FTP服务器,有很多的选项设置.下面介绍了vsftpd的配置文件列表,而所有的配置都是基于vsftpd.conf这个配置文件 的.本文将提供完整的vsftpd.conf ...

  6. 检测MYSQL不同步发邮件通知的脚本

    脚本代码如下:#!/bin/bash                                                                                   ...

  7. 重置kafka的offset

    如果你在使用Kafka来分发消息,在数据处理的过程中可能会出现处理程序出异常或者是其它的错误,会造成数据丢失或不一致.这个时候你也许会想要通过kafka把数据从新处理一遍,我们知道kafka默认会在磁 ...

  8. 在vim中设置将tab自动转化为4个空格

    在vim中,我们只需要简单配置一下就ok了,打开~/.vimrc加上下面的几行(如果已经有了,修改一下数值就行了). set tabstop=4set softtabstop=4set shiftwi ...

  9. 关于修改Android手机的音量

    首先,必须要获取系统的声音服务权限 <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS&qu ...

  10. MR-为什么MR类的变量喜欢定义在方法外面?

    写了一些MR后发现不管是别人写的还是官方给的,比如map方法,变量都是定义在方法外面. 因为之前都是照猫画虎的写的,所以自己也一直这么写,可是为什么呢? 我试了试定义在方法里面,程序照样跑,试了几个程 ...