2016-07-06 23 views
4

我有一个应用程序在前台以及后台使用位置更新。使用CoreLocation框架,我已经实现了该应用程序,以便每隔5分钟将位置更新发送到服务器,并使用this代码作为参考。iOS为什么系统使用位于后台的应用程序杀死应用程序

这在前台运行良好,但是当应用程序进入后台时,它会在30分钟到一个小时后被操作系统杀死。我希望应用能够获得至少8小时的更新,即使在后台也是如此。

此外,该应用程序每小时使用约10%的电池。这与应用程序在后台死亡有关吗?如果是这样,那我该如何解决电池问题?否则,谁能告诉我这是什么问题?

下面是崩溃日志的设备:

Exception Type: 00000020 
Exception Codes: 0x000000008badf00d 
Exception Note: SIMULATED (this is NOT a crash) 
Highlighted by Thread: 2 

Application Specific Information: 
<BKNewProcess: 0x17e74840; com.app.app; pid: 560; hostpid: -1> has active assertions beyond permitted time: 
{(
<BKProcessAssertion: 0x17d78740> id: 560-C9E81E97-90D9-4F95-871E-3DC53372F302 name: Called by UIKit, from <redacted> process: <BKNewProcess: 0x17e74840; com.app.example; pid: 560; hostpid: -1> permittedBackgroundDuration: 180.000000 reason: finishTask owner pid:560 preventSuspend preventIdleSleep preventSuspendOnSleep , 
<BKProcessAssertion: 0x17e6a870> id: 560-BD7B29FC-DABC-42FF-AF17-B277BDB1C59D name: Called by UIKit, from <redacted> process: <BKNewProcess: 0x17e74840; com.app.example; pid: 560; hostpid: -1> permittedBackgroundDuration: 180.000000 reason: finishTask owner pid:560 preventSuspend preventIdleSleep preventSuspendOnSleep 
)} 

对于我用下面的功能,后台任务:

func backgroundTask(){ 
    var application=UIApplication.sharedApplication() 
    var background_task: UIBackgroundTaskIdentifier? 
    background_task = application.beginBackgroundTaskWithExpirationHandler({() -> Void in 
     application.endBackgroundTask(background_task!) 
     background_task = UIBackgroundTaskInvalid 
    }) 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {() -> Void in 
     //run the app without startUpdatingLocation. backgroundTimeRemaining decremented from 600.00 
     self.locationManager.startUpdatingLocation() 
     while (true) { 
      //backgroundTimeRemaining time does not go down. 
      print("Background time Remaining: \(UIApplication.sharedApplication().backgroundTimeRemaining)") 
      NSThread.sleepForTimeInterval(1) 

      break 
      //wait for 1 sec 
     } 
     application.endBackgroundTask(background_task!) 
     background_task = UIBackgroundTaskInvalid 
    }) 

} 

回答

1

你有任何崩溃log.If应用程序不例外终止一些隐藏的bug你应该怀疑内存压力。我认为这篇文章会引导你找到原因突然终止

https://www.raywenderlich.com/23704/demystifying-ios-application-crash-logs

+0

我已经更新了这个问题。拥有崩溃日志。 – Poonam

+0

8badf00d以“应用程序花费太长时间才能启动,终止或响应系统事件而闻名”。 据我所知,从登录线程2东西需要太长的时间来执行主线程,它会导致终止 –

+0

以及如果您的应用程序不断在后台运行,为什么不考虑使用后台模式。我认为这比背景任务更好并保持较长的背景。 –

2

当您的应用进入后台状态切换到significant location updates时,您的应用将持续接收位置更新。您可以致电startMonitoringSignificantLocationChangesCLLocationManger的我认为的对象。而且我也认为你不需要建立后台任务。

检查Apple Documentation,它指出,

如果启动该服务,并且您的应用程序随后终止时,系统会自动是否有新的事件到来将重新启动应用程序进入后台。在这种情况下,选项字典传递给应用程序:willFinishLaunchingWithOptions:和application:didFinishLaunchingWithOptions:您的应用程序委托的方法包含键UIApplicationLaunchOptionsLocationKey,以表明您的应用程序是由于位置事件而启动的。重新启动后,您仍然必须配置位置管理器对象并调用此方法继续接收位置事件。当您重新启动位置服务时,当前事件会立即传递给您的代理。此外,你的位置管理对象的位置属性与最近的位置的对象填充你甚至开始前的位置服务

所以,它会解决你的问题,我认为,这将解决电池的问题也。

第二件事(电池消耗),当你想在后台长时间更新位置时,你不应该设置DesiredAccuracykCLLocationAccuracyBest。您可以将kCLLocationAccuracyThreeKilometers设置为DesiredAccuracy,并且您可以将setDistanceFilter设置为非常大的数字,例如在后台输入99999

您可以参考this so postthis so post

希望这将有助于:)

1

正如@Lion说,进入后台时使用的显着位置更改。我有使用SLC的同样的问题,所以你也会有。当应用程序进入后台时,由于内存警告而被系统杀死。所以我做的是为CoreLocation创建一个单例,它将接收CoreLocation的所有委托调用。

为了重新启动你的服务在后台的情况下,它亡:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) { 

     //NSLog(@"Restarting SCL"); 
     LocationService *loc = [LocationService sharedInstance]; 
     [loc setManagedObjectContext:self.managedObjectContext]; 
} 

LocationService是我的单身。

而且实现这个功能的AppDelegate来处理内存警告声明:

-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application 
{ 
    //Sending notification to every controller to free some memory 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"freeMemory" object:nil userInfo:nil]; 

    SDImageCache *imageCache = [SDImageCache sharedImageCache]; 
    [imageCache clearMemory]; 
    [imageCache clearDisk]; 

    //NSLog(@"Received memory warning!"); 
} 

例如清除图像缓存。 另外,我是你正在使用MapView确保取消任何你不使用,因为是非常昂贵的观点(和漏洞车)。

0

如其他说明,您需要注册才能接收后台位置更新。可能不太清楚的是,这与“随时随地跑在背景中做你自己喜欢的事情”不一样。这意味着在不同的时间,系统会自行决定发送位置数据,您必须尽快处理该位置数据,然后返回。系统选择时将再次调用。可能还有其他位置服务正在运行。系统试图通过合并所有不同的位置客户端来优化这一点。

背景任务与您尝试使用的背景任务完全不一样。当用户退出应用程序时,他们需要“多一点时间”来完成某些操作。就像清理你的数据库或类似的东西。如果让他们继续跑步,你会被杀死。看看你当前的代码,它看起来并不像它实际上做了什么,因为它看起来像在一次调用后突然脱离循环。但是任何调用NSThread.sleepForTimeInterval(1)的代码几乎都可以保证在iOS中不正确。这个电话几乎没有任何理由。但是你不需要后台任务来管理位置更新。

相关问题