2016-07-06 22 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中不正確。這個電話幾乎沒有任何理由。但是你不需要後臺任務來管理位置更新。

相關問題