Multitasking,多任务指的是应用在退出后台后任然可以运行。
关于iOS的具体后台机制请看:http://blog.youkuaiyun.com/isharestudio/article/details/23828421。现在这篇文章以代码实现为主。
1,检测设备是否支持多任务:
- (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中有没有这个方法)。
2,在后台完成一个需要长时间运行的任务
情景:我需要在程序退出后台时向服务器接口请求数据,但没等数据请求下来,程序就已经进入后台被冻结了。
解决方法:
在退出时调用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;
}];