App Programming Guide for iOS -> 后臺執行(三)

當在后臺時引起用戶注意

通知是一種應用被掛起、或在后臺運行、或沒有運行的情況下引起用戶注意的方式。應用可以使用本地通知來顯示警告、播放聲音、印章化應用的圖標、或者三者的組合。例如,一個鬧鐘應用可以使用本地通知來播放鬧鐘聲音并顯示一個警告來關掉鬧鐘。當一個通知被傳遞給用戶的時候,用戶必須根據信息決定是否讓應用回到前臺。(如果應用已經運行在前臺,本地通知只會安靜的傳遞給應用而不會顯示給用戶。)

為了安排本地通知的傳遞,創建一個UILocalNotification類的實例,配置通知參數,并使用UIApplication類的方法來安排它。本地通知對象包含關于用來傳遞的通知類型(聲音、警告、或者徽章)的信息以及發送它的時間(當合適時)。UIApplication類的方法為立刻或在安排的時間傳遞通知提供了選項。

代碼清單3-2顯示了一個使用用戶設定的日期和時間安排一個單次警告的例子。這個例子只配置了一次警告,并在安排一個新的警告之前取消了之前的警告。(你自己的應用可以在任何時刻有不超過128個的本地通知,其中任何一個都可以配置為以指定間隔重復。)警告本身由一個警告框和一個聲音文件組成;當警告觸發時,如果應用在不運行或者在后臺運行的時候,聲音文件會播放。如果應用正處于活動狀態,因此正在前臺運行,作為替代,應用委托的application:didReceiveLocalNotification:方法被調用

代碼清單3-2 安排警告通知

- (void)scheduleAlarmForDate:(NSDate*)theDate

{

    UIApplication* app = [UIApplication sharedApplication];

    NSArray*    oldNotifications = [app scheduledLocalNotifications];

 

    // Clear out the old notification before scheduling a new one.

    if ([oldNotifications count] > 0)

        [app cancelAllLocalNotifications];

 

    // Create a new notification.

    UILocalNotification* alarm = [[UILocalNotification alloc] init];

    if (alarm)

    {

        alarm.fireDate = theDate;

        alarm.timeZone = [NSTimeZone defaultTimeZone];

        alarm.repeatInterval = 0;

        alarm.soundName = @"alarmsound.caf";

        alarm.alertBody = @"Time to wake up!";

 

        [app scheduleLocalNotification:alarm];

    }

}

用于本地通知的聲音文件和用于推送通知的聲音文件具有相同的要求。自定義的聲音文件必須被放置在應用的主束中,并且支持下面格式中的一種:Linear PCM, MA4, μ-Law, 或 a-Law。你也可以指定UILocalNotificationDefaultSoundName常量來為設備播放默認的聲音。當這個通知被發送且聲音被播放時,系統也會在支持震動的設備上觸發震動。

你可以使用UIApplication類的方法來取消安排通知,或者得到通知的列表。更多關于這些方法的信息,參見UIApplication Class Reference。關于配置本地通知的額外信息,參見Local and Remote Notification Programming Guide。

理解你的應用何時在后臺啟動

支持后臺執行的應用可以通過系統重啟來處理傳入的事件。如果應用由于除用戶強退之外的原因而被終止,系統會在下面這些事件發生的時候重啟應用:

  • 對于位置應用:
  • 系統接收到一個與應用所配置的傳送標準匹配的位置更新。
  • 設備進入或退出一個注冊區域。(區域可以是地理區域或iBeacon區域。)
  • 對于音頻應用,音頻框架需要應用來處理一些數據。(音頻應用包括那些播放或使用麥克風的應用。)
  • 對于藍牙應用:
  • 應用扮演從連接的外設獲取數據的中心角色。
  • 應用扮演從連接中心獲取命令的外設角色。
  • 對于后臺下載應用:
  • 應用的推送通知到達,它的通知內容包含值為1的content-available鍵。
  • 系統在有機會的時刻喚醒應用來開始下載新內容。
  • 對于使用NSURLSession類在后臺下載內容的應用,所有與會話對象關聯的任務都成功完成或接收到一個錯誤。
  • Newsstand應用啟動的下載任務完成。

在大多數情況下,系統會不在用戶強退應用后重啟應用。一個例外是位置應用,在iOS 8及更新的版本中,它能在用戶強退之后被重啟。然而在其它情況下,用戶必須明確啟動應用或在應用能被系統從后臺自動啟動之前重啟設備。當設備啟用密碼保護時,系統在用戶首次解鎖設備之前無法從后臺啟動應用。

做一個負責任的后臺應用

在使用系統資源和硬件時,前臺應用總是優先于后臺應用。運行在后臺的應用需要為這種差異做好準備,并在它們運行在后臺的時候調整其行為。具體來說,應用在進入到后臺的時候應該遵循下面的指導:

  • 不要從代碼進行任何OpenGL ES的調用。當運行在后臺的時候,你不能創建EAGLContext對象或者發出任何OpenGL ES繪圖命令。使用這些調用會導致應用被立刻殺死。應用還必須確保任何之前提交的命令在進入后臺之前都已完成。關于如何在進入或移出后臺的時候處理OpenGL ES的信息,參見 OpenGL ES Programming Guide中的Implementing a Multitasking-aware OpenGL ES Application。
  • 在被掛起前取消所有Bonjour相關的服務。當應用進入后臺,并在被掛起前,它應該從Bonjour注銷,并關閉任何與網絡服務相關的socket監聽。掛起的應用不能響應任何傳入的服務請求。關閉這些服務保護它們在其事實上不可用的時候被顯示為可用。如果你沒有關閉Bonjour服務,系統會在應用被掛起的時候自動關閉這些服務。
  • 在基于網絡socket中為處理連接失敗做好準備。系統會在應用被各種原因掛起的時候拆除socket連接。只要你的基于socket的代碼為其他網絡失敗的類型做好了準備,例如信號丟失或者網絡轉換,則不會導致任何異常問題。當應用恢復時,如果在使用socket的時候遇到故障,值需要重新建立連鍵即可。
  • 在進入后臺之前保存應用的狀態。在低內存條件下,后臺應用可以被從內存清除以釋放更多空間。掛起的應用首先會被清除,而且在被清除之前不會有任何通知。因此,應用應該利用iOS 6及更高版本的狀態保存機制來保存它們的界面狀態到磁盤。關于如何支持這個功能的信息,參見Preserving Your App’s Visual Appearance Across Launches。
  • 在進入后臺的時候移除不必要對象的強引用。如果應用維持一個占用大量內存的對象(特別是圖片)的緩存,那就在進入后臺的時候移除所有值像這些緩存的強引用。更多信息,參見Reduce Your Memory Footprint。
  • 在被掛起之前停止使用共享系統資源。與共享系統資源,例如地址簿或日歷數據庫,進行交互的應用,應該在被掛起之前停止使用這些資源。這些資源總是優先提供給前臺應用。當應用被掛起時,如果它被發現正在使用共享資源,應用會被殺死。
  • 避免更新你的窗口和視圖。因為當應用在后臺的時候,它的窗口可視圖不可見,所以你應該避免更新它們。只有在你獲取應用快照之前需更更新窗口內容的情況下才可以例外。
  • 響應連接或斷開外部配件的通知。與外部配件連接的應用,系統會在應用進入后臺的時候自動發送一個斷開連接通知。該應用必須注冊這個通知,以便用它來關閉當前的配件會話。當應用返回到前臺的時候,一個匹配的連接通知會被發送,給應用一個機會來重新連接。更多處理配件連接和斷開通知的信息,參見External Accessory Programming Topics。
  • 當進入后臺的時候清除活動警告的資源。為了在應用之間切換的時候保護內容,系統不會在應用進入后臺的時候自動關閉操作表單(UIActionSheet)或警告視圖(UIAlertView)。在進入后臺之前,由你提供適當地清理行為。例如,你可能想通過編碼的方式取消活動表單或者警告視圖,或者保存足夠的上下文信息以便稍后恢復視圖(在應用程序被終止的情況下)。
  • 在進入后臺之前,刪除視圖上的敏感信息。當應用轉換到后臺,系統得到應用主窗口的一張快照,然后應用轉換回到前臺的時候快照會短暫顯示。在從applicationDidEnterBackground:方法返回之前,你應該隱藏或者遮擋密碼以及其它可能被快照捕獲的敏感的個人信息。
  • 在后臺運行的時候盡可能少做事。給予后臺應用的執行時間比器前臺應用要受到更多的限制。在后臺花費很多時間運行的應用可能會被系統限制或終止。

如果你正在后臺執行一個音頻應用,或者允許在后臺運行的其他類型應用,應用可以照常的響應傳入消息。換句話說,系統可能會在發生低內存警告的時候通知應用。在這種情況下系統需要終止應用來釋放更多的內存,該應用會調用它的applicationWillTerminate:委托方法來執行退出前的最后任務。

選擇不在后臺執行

如果你不想讓應用在后臺執行,你可以通過將UIApplicationExitsOnSuspend鍵(值為YES)添加到在Info.plist 文件來明確的選擇不進入后臺。當應用選擇不進入時,應用會在不運行、非活動、以及活動狀態之間循環,而不會進入到后臺或者掛起狀態。當應用按下Home按鈕退出應用的時候,applicationWillTerminate:方法會被調用,并且在應用終止并進入不運行狀態之前,有大約5秒鐘的時間來清理及退出。

強烈不推薦選擇不進入后臺執行,但是在某些特定情況下可能是首選。具體來說,如果為后臺執行的編碼增加了應用很大的復雜性,終止應用或許是一個更簡便的方案。此外,如果你的應用消耗大量的內存并且無法輕松釋放它,系統會迅速的殺死你的應用來為其他應用騰出空間。因此,選擇終止,而不是切換到后臺,可能會產生相同的結果,并節省開發的時間和精力。

更過關于能包含到Info.plist文件中的鍵的信息,參見Information Property List Key Reference。

(本節結束)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容