方案一:
情景分析:
IOS 应用程序在进入后台之后一般几秒钟之后系统就会把主线程挂起,当然对应的子线程也会被挂起.但是,如果在应用接入后台之前,请求了某个网络数据,当时尚未请求到数据,此时我们想让应用在后台继续尝试请求数据,该如何做呢?
IOS 为我们提供了 - -
-(UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void(^ __nullable)(void))handler ;
endBackgroundTask ;
两者必须成对使用;
具体实现:
// 监听按下Home键,程序进入后台(UIApplicationWillResignActiveNotification-系统提供的监听)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(WillResignActiveNotification) name:UIApplicationWillResignActiveNotification object:nil];
- (void)WillResignActiveNotification{
//得到当前应用程序的UIApplication对象
UIApplication *app = [UIApplication sharedApplication];
//一个后台任务标识符
UIBackgroundTaskIdentifier taskID;
taskID = [app beginBackgroundTaskWithExpirationHandler:^{
//如果超时(一般超时时间为10min),将执行这个程序块,并停止运行应用程序,
[app endBackgroundTask:taskID];
}];
}
// 要执行的请求任务
-(void)task{
// 请求任务
}
//请求完成,告诉系统我们完成了,
[app endBackgroundTask:taskID];
摘自:http://blog.sina.com.cn/s/blog_9cd71e570102wlbf.html
方案二:
正常程序退出后,会在几秒内停止工作;
要想申请更长的时间,需要用到
beginBackgroundTaskWithExpirationHandler
endBackgroundTask
一定要成对出现
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self beginTask];
//在非主线程开启一个操作在更长时间内执行; 执行的动作
aa =0;
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(go:) userInfo:nil repeats:YES];
}
-(void)go:(NSTimer *)tim
{
NSLog(@"%@==%ld ",[NSDate date],aa);
aa++;
if (aa==9) {
[_timer invalidate];
[self endBack]; // 任务执行完毕,主动调用该方法结束任务
}
}
-(void)beginTask
{
NSLog(@"begin=============");
_backIden = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"begin bgend=============");
[self endBack]; // 如果在系统规定时间内任务还没有完成,在时间到之前会调用到这个方法,一般是10分钟
}];
}
-(void)endBack
{
NSLog(@"end=============");
[[UIApplication sharedApplication] endBackgroundTask:_backIden];
_backIden = UIBackgroundTaskInvalid;
}
网友评论