1.iOS其實(shí)是偽后臺(tái)
為什么說iOS是偽后臺(tái)?首先需要了解一下iOS中的后臺(tái)進(jìn)程到底是怎么回事。iOS中所謂的“后臺(tái)駐留”并不是指執(zhí)行中的程序,而是指最近使用過的程序。當(dāng)我們是一個(gè)進(jìn)程進(jìn)入到后臺(tái)的時(shí)候,可以想象成是Command+Tab鍵盤。
一般來說,當(dāng)把一個(gè)app退到后臺(tái)的時(shí)候都會(huì)有5s的時(shí)間執(zhí)行緩沖,有些程序可以要求達(dá)到10分鐘(這個(gè)是需要開發(fā)人員來決定的),因此在按下Home鍵之后,本來的程序就會(huì)退到后臺(tái)中去,最多10分鐘之后還是會(huì)被終止的,這當(dāng)然和蘋果的后臺(tái)管理機(jī)制有關(guān)。
2.iOS多任務(wù)
自從出現(xiàn)操作系統(tǒng)以來就沒有多任務(wù),就跟多線程一樣,無非是CPU在極短的時(shí)間里在多個(gè)進(jìn)程之間運(yùn)作罷了。而單任務(wù)是當(dāng)前的進(jìn)程獨(dú)享資源。簡單來說,iOS4 之后APP的類型可以分為三種:
1. 保存現(xiàn)場。
即:按下Home鍵10秒內(nèi)直接殺死進(jìn)程,并釋放內(nèi)存。一般說來,所有程序進(jìn)入背景后都還有5 秒的執(zhí)行緩沖時(shí)間,有些程序可以要求延長到10 分鐘(這些當(dāng)然是由開發(fā)人員在設(shè)計(jì)與提交程式時(shí)決定和聲明);因此,在你按下Home 鍵后,本來的程式就會(huì)退到背景,如果它有額外的背景執(zhí)行作業(yè),超過10 分鐘還是會(huì)被iOS 中止。
2.iOS支持的“多任務(wù)”。
即:按下Home鍵轉(zhuǎn)入多任務(wù)狀態(tài),保留在內(nèi)存中,但只能系統(tǒng)允許的動(dòng)作:比如GPS,比如Streaming Music等等。
3.真正的桌面級別的多任務(wù)。
即:只有Safari/Mail才是真正的多任務(wù),蘋果嫡系大都都不是。這個(gè)級別的app在后臺(tái)是沒有任何限制動(dòng)作。(對于無限制動(dòng)作的程序,一是會(huì)在用戶無察覺的情況下耗光電力,二是會(huì)有安全上面的問題)。
3.設(shè)備多任務(wù)
Apple在出于性能的考慮上,之前并不是所有的設(shè)備都是支持多任務(wù)的。通常,當(dāng)用戶按一下Home鍵的時(shí)候,當(dāng)前應(yīng)用就會(huì)進(jìn)入后臺(tái),應(yīng)用在進(jìn)入后臺(tái)之后就會(huì)被suspend(掛起)狀態(tài),此時(shí)不再去執(zhí)行任何的代碼,如果系統(tǒng)在運(yùn)行其他程序出現(xiàn)內(nèi)存警告的時(shí)候就會(huì)優(yōu)先將先suspend的程序先退出系統(tǒng),只有當(dāng)用戶和再次啟動(dòng)APP的時(shí)候才會(huì)從掛起的狀態(tài)變成喚醒的狀態(tài),這個(gè)是基本的多任務(wù)特新。
那么既然是多任務(wù)應(yīng)該會(huì)在應(yīng)用進(jìn)入后臺(tái)時(shí)做一些處理,比如暫停界面的定時(shí)刷新或者是網(wǎng)絡(luò)請求,同時(shí),或者需要在程序進(jìn)入前臺(tái)時(shí)候執(zhí)行一些恢復(fù)操作,在應(yīng)用的Appdelegate中有兩個(gè)方法用于處理這些消息:
(void)applicationDidEnterBackground:(UIApplication*)application
{
//進(jìn)入后臺(tái)時(shí)要進(jìn)行的處理
}
-?(void)applicationWillEnterForeground:(UIApplication*)application
{
//進(jìn)入前臺(tái)時(shí)要進(jìn)行的處理
}
如果是在其他的對象中處理后臺(tái)消息的時(shí)候,需要使用到系統(tǒng)的兩個(gè)通知UIApplicationDidEnterBackgroundNotification和UIApplicationWillEnterForegroundNotification。
那么在開發(fā)中我們往往是需要在后臺(tái)做一些事情的,比如說GPS、播放音樂等。那么這個(gè)時(shí)候需要我們手動(dòng)去聲明后臺(tái)的任務(wù):
在Info.plist中添加UIBackgroundModes鍵值,它包含一個(gè)或多個(gè)string的值,包括:
audio:在后臺(tái)提供聲音播放功能,包括音頻流和播放視頻時(shí)的聲音
location:在后臺(tái)可以保持用戶的位置信息
voip:在后臺(tái)使用VOIP功能
前面的每一個(gè)value讓系統(tǒng)知道我們的應(yīng)用程序應(yīng)當(dāng)要在適當(dāng)?shù)臅r(shí)候被喚醒,比如說一個(gè)應(yīng)用程序在后臺(tái)的時(shí)候也需要播放音樂,添加audio鍵用來告訴系統(tǒng)框架,需要繼續(xù)播放音頻,并且可以在合適的時(shí)間間隔下回調(diào)應(yīng)用程序;如果應(yīng)用程序不包括此項(xiàng),任何音頻播放在移到后臺(tái)后將停止運(yùn)行。
后臺(tái)voip支持
由于voip應(yīng)用需要一個(gè)長連接到服務(wù)器,為了讓這類應(yīng)用能正常工作,iOS中加入后臺(tái)voip支持特性。為支持這一特性,需要在Info.plist文件中UIBackgroundModes字段對應(yīng)的數(shù)組中增加“voip”字符串。
此外你仍然需要配置一下你的網(wǎng)絡(luò)連接,以便支持后臺(tái)連接。iOS提供的網(wǎng)絡(luò)連接庫有幾種,下面一一說明:
a、如果你使用的是NSStream,如NSInputStream或NSOutputStream,需要調(diào)用setProperty:forKey:將Key為NSStreamNetworkServiceType的value設(shè)置為
NSStreamNetworkServiceTypeVoIP;
b、如果你使用NSURLRequest,需要調(diào)用setNetworkServiceType:將網(wǎng)絡(luò)類型設(shè)置為NSURLNetworkServiceTypeVoIP;
c、如果你使用CFStream,如CFReadStreamRef或CFWriteStreamRef,需要調(diào)用CFReadStreamSetProperty或CFWriteStreamSetProperty將kCFStreamNetworkServiceType屬性設(shè)置為kCFStreamNetworkServiceTypeVoIP。