iOS 多任务(后台服务)


Multitasking,多任务指的是应用在退出后台后任然可以运行。 

关于iOS的具体后台机制请看:http://blog.csdn.net/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;
    }];










你可能感兴趣的:(iOS 多任务(后台服务))