2015-02-06 78 views
0

我的应用程序通过BLE从外设下载了一堆数据。如果我锁定屏幕,我的应用程序将移动到背景中并开始后台任务。下载完成的很好,但如果处理(因为数据量很大而花费相当长的时间)开始应用程序的分割,因为它无法连接到数据库。结束后台任务并等到应用程序再次变为活动状态 - BLE处理数据

我想停止执行在这一点,并等待应用程序再次变得活跃,但不知何故,我不能实现这一点。我想我需要某种信号量来等待应用程序变得活跃。

这里我到目前为止的代码:

- (void)viewDidLoad 
{ 
    //Some other code 

    //initialize flag   
    isInBackgroud = NO; 

    // check if app is in the background 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil]; 

    // check if app is in the foreground 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterForeground) name:UIApplicationDidBecomeActiveNotification object:nil]; 
} 

- (void)appDidEnterBackground { 
    NSLog(@"appDidEnterBackground"); 
    isInBackground = YES; 
    UIApplication *app = [UIApplication sharedApplication]; 
    NSLog(@"remaining Time: %f", [app backgroundTimeRemaining]); 
    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
     NSLog(@"expirationHandler"); 
     [app endBackgroundTask:bgTask]; 
     bgTask = UIBackgroundTaskInvalid; 
    }]; 
} 

- (void)appDidEnterForeground { 
    NSLog(@"appDidEnterForeground"); 
    isInBackground = NO; 
    if (bgTask != UIBackgroundTaskInvalid) { 
     UIApplication *app = [UIApplication sharedApplication]; 
     [app endBackgroundTask:bgTask]; 
     bgTask = UIBackgroundTaskInvalid; 
    } 
} 

//BLE connection and reading data via notification 
//when finished [self processData] is called. 

- (void)processData { 
    if (isInBackground) { 
     //set reminder 
     UILocalNotification *localNotification = [[UILocalNotification alloc] init]; 
     localNotification.fireDate = [NSDate date]; 
     localNotification.alertBody = [NSString stringWithFormat:@"Data was downloaded, return to the application to proceed processing your data."]; 
     localNotification.timeZone = [NSTimeZone defaultTimeZone]; 
     [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; 
     UIApplication *app = [UIApplication sharedApplication]; 

     //end background task 
     [app endBackgroundTask:bgTask]; 
     bgTask = UIBackgroundTaskInvalid; 

     //wait for application to become active again 
     while (isInBackground) { 
      NSLog(@"isInBackground"); 
      NSLog(@"remaining Time: %f", [app backgroundTimeRemaining]); 
      sleep(1); 
     } 

     //process data 
    } 

所以我必须声明,如果我叫[app endBackgroundTask:bgTask];应用程序只是继续运行,但随后崩溃时,我想连接到我的数据库。这就是为什么我添加了while(isInBackground)循环。我知道这不是好的做法,因为它会在注意时积极浪费CPU时间。我应该在那个时候使用信号量,但是我不知道如何去做。

因为我在那个循环中积极保持,appDidEnterForegronund永远不会被调用,循环将永远运行。

回答

3

您不应该循环,因为您的应用程序只有在iOS停止之前处理这么长时间才能处理。相反,当你的应用程序进入后台时,设置一个状态变量,它位于后台。为前景做同样的事情。

如果你在前台,只更新数据库,否则设置一个状态变量,告诉你的应用程序你已经完成了下载,但仍然需要处理数据。如果需要,存储数据。

然后,当您的应用程序重新启动时,检查该变量的状态并进行处理。

而不是坐在等待某些状态改变的循环中,设置变量并使用事件驱动的编程。

+0

Thakns,不知何故,我没有看到:P – daydr3amer 2015-02-06 14:58:33

相关问题