1. 程式人生 > >ios 實現在後臺執行的長期任務

ios 實現在後臺執行的長期任務

       當用戶點選home鍵,ios系統會讓我們的程式進入到後臺狀態,對於許多應用來說,程式進入到後臺後會被掛起,掛起應用能夠提高電池的使用時間,還能讓ios把重要的系統資源分配給正在前臺執行的程式。

      但是在有些情況下,我們需要程式在進入後臺時仍然正常執行,比如一個徒步類的應用,它需要一直記錄使用者的位置,來生成一張使用者的路線圖。一個音訊應用在使用者鎖屏期間仍能播放音樂.還有一些應用可能需要在後臺下載資料,在應用進入到前臺時,直接顯示。(縮短使用者的等待時間)。當我們覺得自己的應用需要在後臺長時間執行時,ios系統為我們提供了三種方法來實現這個種機制:

    1. 在前臺啟動了一個短期任務的應用在程式進入到後臺進,可以向ios系統要一點時間來完成這個短期任務

     2.在前臺啟動了一些下載任務的應用可以把那些下載任務移交給ios系統管理。當程式被掛起或被使用者結束的時候,仍能繼續下載。

    3. 那些需要在後臺執行的應用可以根據執行的需要來宣告他們需要的後臺執行模式

    我們應避免任務在後臺執行,除非這個後臺任務能提高應用的整體使用者體驗。在使用者啟動了一個新的應用或使用者鎖屏會使用我們的應用進入到後臺,這兩種情況下,使用者的想法是:“我現在不需要再使用這個應用了,我想玩玩別的”。在這種情況下,如果應用仍在後臺執行會非常的費電,可能會讓使用者強行退出我們的應用。所以一定要仔細斟酌我們的應用是否真的需要在後臺執行。

執行短期任務(執行時間有限的任務)

在任務完成後,我們的應用必須呼叫endBackgroundTask來告訴ios系統,任務執行完啦。現在你可以掛起我的應用了。

 每次呼叫beginBackgroundTaskWithName 或 beginBackgroundTaskWithExpirationHandler 都生返回一個唯一的標識,(這個標識用來與我們在後臺執行的任務一一對應),當在後臺執行的任務執行完畢後,必須呼叫endBackgroundTask來告訴ios系統任務執行完畢了(endBackgroundTask需要上面的標識來做為引數,表明對應的任務結束了)。如果不呼叫endBackgroundTask,應用會被結束掉。如果我們提供了ExpirationHandler方法的話,ios系統會呼叫它,來給我們機會呼叫endBackgroundTask.

  我們不需要等到程式進入到後臺時再開啟一個後臺任務(廢話,等一下有個標準使用者的demo),更好的設計方案是:在開啟一個任務前調beginBackgroundTaskWithName or beginbackgroundTaskWithExpirationHandler 然後在任務完成時呼叫endBackgroundTask。

 下面的demo演示了在我們的應用進行到後臺時如何開啟一個長期執行的任務。在這個demo中,開始後臺任務進使用了一個expiration handler 來防止任務執行超時。任務被新增到一個全域性佇列中非同步執行,來儲存在執行applicationDidEnterBackground方法能正常返回。

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
        // Clean up any unfinished task business by marking where you
        // stopped or ending the task outright.
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];
 
    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 
        // Do the work associated with the task, preferably in chunks.
 
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
}

Note: Always provide an expiration handler when starting a task, but if you want to know how much time your app has left to run, get the value of the backgroundTimeRemaining property of UIApplication.

 注意:一定要為expirationHandler指定一個程式碼塊,在這個程式碼塊中判斷任務是執行完畢,如果沒有執行完畢,關閉任務,再關閉對應的後臺任務(
endBackgroundTask
),當ios系統執行expirationHandler時,說明我們的應用馬上就要被掛起了,所以在這個方法中執行的程式碼一定要精簡。(就是不能執行太耗時的操作。)

在後臺進行下載任務