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;
    }];










  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值