標籤:
1.iOS其實是偽後台為什麼說iOS是偽後台?首先需要瞭解一下iOS中的後台進程到底是怎麼回事。iOS中所謂的“後台駐留”並不是指執行中的程式,而是指最近使用過的程式。當我們是一個進程進入到背景時候,可以想象成是Command+Tab鍵盤。一般來說,當把一個app退到背景時候都會有5s的時間執行緩衝,有些程式可以要求達到10分鐘(這個是需要開發人員來決定的),因此在按下Home鍵之後,本來的程式就會退到後台中去,最多10分鐘之後還是會被終止的,這當然和蘋果的後台管理機制有關。
2.iOS多任務自從出現作業系統以來就沒有多任務,就跟多線程一樣,無非是CPU在極短的時間裡在多個進程之間運作罷了。而單任務是當前的進程獨享資源。簡單來說,iOS4 之後APP的類型可以分為三種:1. 儲存現場。即:按下Home鍵10秒內直接殺死進程,並釋放記憶體。一般說來,所有程式進入背景後都還有5 秒的執行緩衝時間,有些程式可以要求延長到10 分鐘(這些當然是由開發人員在設計與提交程式時決定和聲明);因此,在你按下Home 鍵後,本來的程式就會退到背景,如果它有額外的背景執行作業,超過10 分鐘還是會被iOS 中止。2. iOS支援的“多任務”。即:按下Home鍵轉入多任務狀態,保留在記憶體中,但只能系統允許的動作:比如GPS,比如Streaming Music等等。3. 真正的案頭層級的多任務。即:只有Safari/Mail才是真正的多任務,蘋果嫡系大都都不是。這個層級的app在後台是沒有任何限制動作。(對於無限制動作的程式,一是會在使用者無察覺的情況下耗光電力,二是會有安全上面的問題)。
3.裝置多任務Apple在出於效能的考慮上,之前並不是所有的裝置都是支援多任務的。通常,當使用者按一下Home鍵的時候,當前應用就會進入後台,應用在進入後台之後就會被suspend(掛起)狀態,此時不再去執行任何的代碼,如果系統在運行其他程式出現記憶體警告的時候就會優先將先suspend的程式先退出系統,只有當使用者和再次啟動APP的時候才會從掛起的狀態變成喚醒的狀態,這個是基本的多任務特新。那麼既然是多任務應該會在應用進入後台時做一些處理,比如暫停介面的定時重新整理或者是網路請求,同時,或者需要在程式進入前台時候執行一些恢複操作,在應用的Appdelegate中有兩個方法用於處理這些訊息:(void)applicationDidEnterBackground:(UIApplication*)application { //進入後台時要進行的處理 } - (void)applicationWillEnterForeground:(UIApplication*)application { //進入前台時要進行的處理 } 如果是在其他的對象中處理後台訊息的時候,需要使用到系統的兩個通知UIApplicationDidEnterBackgroundNotification和UIApplicationWillEnterForegroundNotification。那麼在開發中我們往往是需要在後台做一些事情的,比如說GPS、播放音樂等。那麼這個時候需要我們手動去聲明背景任務:在Info.plist中添加UIBackgroundModes索引值,它包含一個或多個string的值,包括:audio:在後台提供聲音播放功能,包括音頻流和播放視頻時的聲音location:在後台可以保持使用者的位置資訊voip:在後台使用VOIP功能前面的每一個value讓系統知道我們的應用程式應當要在適當的時候被喚醒,比如說一個應用程式在背景時候也需要播放音樂,添加audio鍵用來告訴系統架構,需要繼續播放音頻,並且可以在合適的時間間隔下回調應用程式;如果應用程式不包括此項,任何音頻播放在移到後台後將停止運行。後台voip支援由於voip應用需要一個長串連到伺服器,為了讓這類應用能正常工作,iOS中加入後台voip支援特性。為支援這一特性,需要在Info.plist檔案中UIBackgroundModes欄位對應的數組中增加“voip”字串。此外你仍然需要配置一下你的網路連接,以便支援後台串連。iOS提供的網路連接庫有幾種,下面一一說明:
a、如果你使用的是NSStream,如NSInputStream或NSOutputStream,需要調用setProperty:forKey:將Key為NSStreamNetworkServiceType的value設定為NSStreamNetworkServiceTypeVoIP;
b、如果你使用NSURLRequest,需要調用setNetworkServiceType:將網路類型設定為NSURLNetworkServiceTypeVoIP;
c、如果你使用CFStream,如CFReadStreamRef或CFWriteStreamRef,需要調用CFReadStreamSetProperty或CFWriteStreamSetProperty將 kCFStreamNetworkServiceType屬性設定為kCFStreamNetworkServiceTypeVoIP。
iOS後台運行機制簡解