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>
如果该应用不能在后台执行,则会返回 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>
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>
相关文章推荐
- 【iOS】idfa查找
- iOS 截屏并保存在本地
- iOS状态栏颜色修改
- AutoLayout三个重要的概念
- 适配iPad和iPhone
- CocoaPods + 自定义静态库 -> 多工程连编
- IOS博客项目搭建-09-OAuth02授权
- ios逆向小试牛刀之操作手记
- iOS开发之 [NSNull length]:unrecognized selector sent
- IOS开发探索(一):CocoalPods相关
- iOS - 自定义启动图
- iOS 对于block的理解
- IOS中 Block简介与用法(一)
- [置顶] block一点也不神秘————如何利用block进行回调
- iOS非常重要的 block回调
- iOS之单例模式初探
- iOS设置圆角图片的方法及对比
- iOS的JS和OC代码互相调用
- IOS学习 GCD 延时执行三种方法 并行/串行/主队列综合练习 队列组 shift+command+o快速查找
- OC阅读笔记八:分类(上)