iOS申請持續的後臺時間

iOS申請持續的後臺時間

xcode

 安全

因爲蘋果的後臺機制,當咱們按下home鍵的時候,全部線程包括主線程的任務都會被掛起,一些資源好比socket也會被系統回收,會致使不少問題,好比一個很重要的資源中斷下載,或者定時器方法被暫停等等。服務器

 

蘋果在4.0之後提供了一種申請後臺時間的機制:app


- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handlersocket

聲明:async

標記要開始一個新的長期運行的後臺任務函數

 

參數:
handler oop

應用程序後臺剩餘時間快到達爲0的時候的一個處理回調,你應該使用這個回調來作一些清理工做和後臺任務結束的標記,未能明確地結束任務將致使APP的終止,這個處理回調將在主線程中被同步調用,並馬上阻止app的暫停當app被通知的時候。
spa


返回值:.net

一個新的後臺任務的惟一的標示符,你必須將這個值傳給endBackgroundTask:方法來標記任務的結束。若是沒法在後臺運行這個方法將返回UIBackgroundTaskInvalid。

 

描述:

這個方法會讓你的app轉到後臺之後繼續運行一段時間,你能夠在一個任務未完成將會致使影響用戶體驗的狀況下調用此方法。例如,你能夠調用次方法來獲取足夠的時間來傳輸一個很重要的文件到遠程服務器或者至少嘗試標記一些錯誤。你不該該隨意的調用這個方法來保持你的app在後臺長期運行。

 

每一次調用此方法都應該有對應的endBackgroundTask:方法,app的後臺運行時間是有限的(你能夠經過backgroundTimeRemaining屬性來獲取這個可用時間)若是在這個時間耗盡以前你沒有調用endBackgroundTask:方法來結束相應的每一個後臺任務,系統就會殺掉這個app。若是你提供了這個handler,系統將會在到期時間到達以前調用這個handler來給你這個機會來終止你的任務。

 

你能夠在你應用程序執行的任何地方調用這個方法,你也能夠屢次調用這個方法來標記多個並行的後臺任務,然而,每一個任務必須分開終止,你能夠經過這個方法的返回值來標記不一樣的任務。

 

爲了便於調試,這個方法是基於調用函數或者方法的名稱來爲任務命名的,若是你須要自定義這個名稱,可使用beginBackgroundTaskWithName:expirationHandler:方法來代替。

 

這個方法能夠在非主線程中安全調用。

注意:

若是你在調試後臺任務遇到麻煩,你能夠嘗試使用beginBackgroundTaskWithName:expirationHandler:方法太替代這個方法,這個方法提供相同的功能可是能夠給你一個調試可用的任務名稱。

 

使用方法:

如下在子線程中打開一個定時器,並在應用程序進入到後臺之後打開回調

 

[objc]  view plain  copy
  1. [[NSNotificationCenter defaultCenter]  addObserver:self selector:@selector(applicationDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];  
  2.   
  3. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  4.       
  5.     NSTimer* timer = [NSTimer timerWithTimeInterval:10.0  
  6.                                              target:self  
  7.                                            selector:@selector(timerHandle)  
  8.                                            userInfo:nil  
  9.                                             repeats:YES];  
  10.       
  11.     [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];  
  12.       
  13.     [[NSRunLoop currentRunLoop]run];  
  14.       
  15.     });  

 

 

如下回調方法是申請後臺時間,當系統沒法再給更多的時間的時候會調用handler中的block塊,在這個block中,咱們要作相應的清理工做並終止後臺任務(備註:若是咱們不調用endBackgroundTask:來終止相應的後臺任務的話,好像還能繼續運行後臺任務,不知道爲啥,蘋果文檔是說你不本身終止,系統會給你kill掉)

 

[objc]  view plain  copy
  1. -(void)applicationDidEnterBackground  
  2. {  
  3.     UIApplication*  application = [UIApplication sharedApplication];  
  4.   
  5.     bgTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{  
  6.           
  7.         NSLog(@"Starting background task with %f seconds remaining", application.backgroundTimeRemaining);  
  8.           
  9.         if (bgTaskIdentifier != UIBackgroundTaskInvalid)  
  10.         {  
  11.             [application endBackgroundTask:bgTaskIdentifier];  
  12.             bgTaskIdentifier = UIBackgroundTaskInvalid;  
  13.         }  
  14.     }];  
  15. }  

[objc]  view plain  copy
  1. - (void)timerHandle  
  2. {  
  3.     NSLog(@"timerHandle");  
  4.       
  5. }  

 

我在子線程中開啓了一個定時器,每隔10秒打印一次timerHandle,我在應用程序進入到後臺之後申請了更多的後臺時間,所以,當我按下home或者鎖屏的時候,定時器方法會繼續調用。

 

咱們把定時器方法修改以下:

 

[objc]  view plain  copy
  1. - (void)timerHandle  
  2. {  
  3.     NSLog(@"timerHandle");  
  4.       
  5.     UIApplication*  application = [UIApplication sharedApplication];  
  6.       
  7.     if (bgTaskIdentifier != UIBackgroundTaskInvalid)  
  8.     {  
  9.         [application endBackgroundTask:bgTaskIdentifier];  
  10.         bgTaskIdentifier = UIBackgroundTaskInvalid;  
  11.     }  
  12. }  

 

當定時器一啓動咱們就按下home鍵,在第一個10秒會打印timerHandle,而後應用程序會終止後臺任務,直到咱們從新進入到前臺,纔會繼續打印信息。

 

同理,若是我此時是在後臺下載文件,完成之後應該經過以上方法來終止相應的後臺任務,按照蘋果文檔說的不能什麼事情也沒幹還讓程序在後臺運行,

 

以上的bgTaskIdentifier是全局的UIBackgroundTaskIdentifier型變量,用來標示不一樣的後臺任務的。好比說我有一個定時器須要後臺運行,還有一個文件須要後臺下載,那麼咱們就要經過這個不一樣的標示符來分開申請後臺時間,並在後臺完成任務之後分別去終止相應地後臺任務。

相關文章
相關標籤/搜索