您的位置:首页 > 移动开发 > IOS开发

iOS 后台线程

2016-04-01 00:57 411 查看
首先介绍一下iOS应用运行过程中会经历的5种状态:

Not Running:非运行状态

Inactive:前台非活动状态

Active:前台活动状态

Background:后台状态

Suspended:挂起状态

在应用状态迁移过程中回调的方法有以下几种:

application:didFinishLaunchingWithOptions:应用启动并进行初始化时

applicationDidBecomeActive:应用进入前台并处于活动状态时

applicationWillResignActive:应用从活动状态进入到非活动状态时

applicationDidEnterBackground:应用进入后台时

applicationWillEnterForeground:应用进入到前台,但还没有处于活动状态时

applicationWillTerminate:应用被终止时

本文主要描述应用的后台运行。当应用在前台运行时,点击Home键,根据应用属性文件中的Application does not run in background的值(Yes/No),此时该应用将分两种情况执行,经历的状态也有一点区别。

(1) 应用可以在后台运行

Active   -->  Inactive  -->  Background  -->  Suspended

(2) 应用不可以在后台运行

Active -->  Inactive  -->  Background  -->  Suspended  -->  Not Running

我们知道,应用进入后台时,会调用applicationDidEnterBackground:方法,注意:不要在 applicationDidEnterBackground: 方法中执行耗时较长的任务,否则iOS系统可能直接从内存中删除该应用。另外,对于多线程任务,当应用进入后台时,如果该任务还没有执行完成,应用进入后台时该任务会被暂停。

为了请求更多的后台运行时间,可以调用 UIApplication 对象的 beginBackgroundTaskWithExpiration Handler: 方法。

首先使用默认通知中心监听UIApplicationDidEnterBackgroundNotification(应用进入后台通知),然后调用enterBack:方法。

<span style="font-size:18px;">- (void)viewDidLoad
{
[super viewDidLoad];
// 使用默认通知中心监听应用转入后台的过程
// 应用转入后台时会向通知中心发送UIApplicationDidEnterBackgroundNotification
// 从而激发enterBack:方法
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(enterBack:)
name:UIApplicationDidEnterBackgroundNotification
object:[UIApplication sharedApplication]];
}</span>
然后在enterBack:方法中调用 UIApplication 对象的 beginBackgroundTaskWithExpiration Handler: 方法获取更多的后台运行时间,并调用 dispatch_async() 方法将指定代码块(需要在后台执行的任务)提交给后台执行,后台任务完成或超时后都要调用 UIApplication 对象的 endBackgroundTask: 方法来结束后台任务。

<span style="font-size:18px;">- (void) enterBack:(NSNotification*)notification
{
UIApplication* app = [UIApplication sharedApplication];
// 定义一个UIBackgroundTaskIdentifier类型(本质就是NSUInteger)的变量,
// 该变量将作为后台任务的标示符
__block UIBackgroundTaskIdentifier backTaskId;
/* beginBackgroundTaskWithExpirationHandler: 方法默认请求额外获取10分钟的后台时间 */
backTaskId = [app beginBackgroundTaskWithExpirationHandler:^
{
NSLog(@"===在额外申请的10分钟内依然没有完成任务===");
// 结束后台任务
[app endBackgroundTask:backTaskId];
}];
if(backTaskId == UIBackgroundTaskInvalid)
{
NSLog(@"===iOS版本不支持后台运行,后台任务启动失败===");
return;
}
// 将代码块以异步方式提交给系统的全局并发队列
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
, ^{
NSLog(@"===额外申请的后台任务时间为:%f==="
, app.backgroundTimeRemaining);
// 其他内存清理的代码也可在此处完成
for(int i = 0 ; i < 100 ; i ++)
{
NSLog(@"下载任务完成了%d%%" , i );
// 暂停10秒模拟正在执行后台下载
[NSThread sleepForTimeInterval:1];
}
NSLog(@"===剩余的后台任务时间为:%f==="
, app.backgroundTimeRemaining);
// 结束后台任务
[app endBackgroundTask:backTaskId];
});
}</span>
<span style="font-size:18px;">通过 <span style="font-family: Arial, Helvetica, sans-serif;">beginBackgroundTaskWithExpirationHandler: 方法来请求更多的后台运行时间,当该应用的后台时间减少到0时,将会调用 handler 代码块。</span></span>
<span style="font-size:18px;">- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler</span>

如果该应用不能在后台执行,则会返回 UIBackgroundTaskInvalid;否则会返回后台任务的标识符,然后将该标识符传给
<span style="font-size:18px;">- (void)endBackgroundTask:(UIBackgroundTaskIdentifier)identifier <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">方法,用来结束任务。</span></span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: