轉載自:looyao's blog
當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掉.