关于iOS的具体后台机制请看:http://blog.csdn.net/isharestudio/article/details/23828421。现在这篇文章以代码实现为主。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { if ([self isMultitaskingSupported]) { NSLog(@"Multitasking is supported."); }else { NSLog(@"Multitasking is not supported."); } self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; } - (BOOL) isMultitaskingSupported { BOOL result = NO; if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) { result = [[UIDevice currentDevice] isMultitaskingSupported]; } return result; }
[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)
用于判断当前设备的操作系统支不支持多任务(即SDK中有没有这个方法)。
情景:我需要在程序退出后台时向服务器接口请求数据,但没等数据请求下来,程序就已经进入后台被冻结了。
解决方法:
在退出时调用UIApplication的实例方法 beginBackgroundTaskWithExpirationHandler:
在完成后调用UIApplication的实例方法 endBackgroundTask:
- (void)timerMethod:(NSTimer *)paramSender { NSTimeInterval backgroundTimeRemaining = [[UIApplication sharedApplication] backgroundTimeRemaining]; if (backgroundTimeRemaining == DBL_MAX) { NSLog(@"Background Time Remaining = Undetermined"); }else { NSLog(@"Background Time Remaining = %.02f Seconds",backgroundTimeRemaining); } } - (void)applicationDidEnterBackground:(UIApplication *)application { if (![self isMultitaskingSupported]) { return; } self.myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timerMethod:) userInfo:nil repeats:YES]; self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^(void){ [self endBackgroundTask]; }]; } - (void)endBackgroundTask { dispatch_queue_t mainQueue = dispatch_get_main_queue(); __weak AppDelegate *weakSelf = self; dispatch_async(mainQueue, ^(void){ AppDelegate *strongSelf = weakSelf; if (strongSelf) { [strongSelf.myTimer invalidate]; [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier]; strongSelf.backgroundTaskIdentifier = UIBackgroundTaskInvalid; } }); } - (void)applicationWillEnterForeground:(UIApplication *)application { if (self.backgroundTaskIdentifier != UIBackgroundTaskInvalid) { [self endBackgroundTask]; } }
当应用点击Home退出后,后台开始打印时间数据,直到时间结束或重回到前台时停止。
我在公司项目的例子使用,就是退出后需要等待服务器相应数据然后做相应操作,最后在监听退出的方法中添加以下代码轻松解决。
//为了响应服务器返回数据,向系统申请后台运行 UIApplication *application = [UIApplication sharedApplication]; self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^(void){ //如果后台运行时间过长(允许后台运行的时间只有3分钟左右),将执行这个程序块,停止运行应用程序 [application endBackgroundTask:self.backgroundTaskIdentifier]; self.backgroundTaskIdentifier = UIBackgroundTaskInvalid; }];