當App進入後台時(按下Home鍵), App會被系統暫停, 所有的程式邏輯都會停止, App還是駐留記憶體中, 除非被使用者強制退出, 或者被系統kill掉(為了保證正在前台啟動並執行App有足夠的記憶體, 系統會選擇性的kill掉背景其他App), 當然這個和本文討論的主題不太相關, 本文要講的是如何讓進入背景App爭取更多的已耗用時間而不是被馬上暫停掉. 當程式進入後台, 我們有時需要做一些網路通訊, 比如向伺服器發送一些狀態資料, 可能這些操作不會太耗時, 但是會被系統暫停掉, 我們需要爭取一些時間完成這些操作,
下面講如何爭取更多的已耗用時間.
假設我們需要後台執行的邏輯寫在RootController中, 那麼在RootController中, 先聲明一個執行個體變數, 和一個方法, 類似
@interface RootViewController : UIViewController
{
UIBackgroundTaskIdentifier backgroundTask; //用來儲存後台運行任務的標示符
}
- (void)startBackgroundTask;
實現:
- (void)startBackgroundTask
{
UIApplication *application = [UIApplication sharedApplication];
//通知系統, 我們需要後台繼續執行一些邏輯
backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{
//超過系統規定的後台已耗用時間, 則暫停後台邏輯
[application endBackgroundTask:backgroundTask];
backgroundTask = UIBackgroundTaskInvalid;
}];
//判斷如果申請失敗了, 返回
if (backgroundTask == UIBackgroundTaskInvalid) {
NSLog(@"beginground error");
return;
}
//已經成功向系統爭取了一些後台已耗用時間, 實現一些邏輯, 如網路處理
//some code
}
當我們的任務已經完成, 如網路請求完成, 最好通知系統背景邏輯已經完成了
//如, 網路處理結束
- (void)requestFinished
{
if (backgroundTask != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
backgroundTask = UIBackgroundTaskInvalid;
}
}
系統進入後台會自動調用Appdelegate中的- (void)applicationDidEnterBackground:(UIApplication *)application 這個方法, 我們要在這裏手動調用RootController的startBackgroundTask方法
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[rootController startBackgroundTask];
}
這樣, 我們就可以在後台繼續運行我們需要處理的邏輯了, 這裡需要注意兩點:
1、App進入後台最多隻能運行10分鐘,
2、如果超過了系統允許的時間沒有調用endBackgroundTask:這個方法繼續執行邏輯, App會被系統kill掉.
參考資料:
UIApplication
Class Reference
- 轉載請註明出處:looyao's blog
- 本文連結地址:iOS
App進入後台擷取更多的已耗用時間