1、iOS的「僞後臺」程序程序員
首先,先了解一下iOS 中所謂的「後臺進程」究竟是怎麼回事吧?web
Let me be as clear as I can be: the iOS multitasking bar does not contain "a list of all running apps". It contains "a list of recently used apps". The user never has to manage background tasks on iOS.數組
首先咱們得搞清楚的是,iOS 中所謂的「後臺駐留」並非指「執行中的程序」,而是「最近使用過的程序」,也能夠瞧瞧Apple 的知識庫文章怎麼寫的:
按兩下主畫面按鈕後,顯示的是「最近用過的應用程序」,因此別把它想成Mac OS X 中的Command + Tab 鍵所顯示的切換程序列;你能夠試試看將iPhone 關機再開機,而後按兩下Home 鍵,應該會發現先前那些程式仍是出如今那裏,由於它實際上是你最近使用過的程序使用記錄,或像是瀏覽器中的瀏覽記錄)。
若是你一個一個去清除 "後臺駐留" 的程序,就像是一筆一筆刪除瀏覽記錄中的項目同樣,是沒有太大意義的(除非你不想讓其餘人看到你曾經用過什麼程式,或者想殺時間、太無聊了),也不會對電力或記憶體有什麼幫助。
iOS 的多任務處理實際上是很聰明的,系統會自動停止在背景執行的程序,在有須要時,也會將被停止的程式suspended(注:"停止的程式"不是指關閉程序,而是指由前臺轉向後臺的程序,程序在後臺並不真正運行,不要和關閉程序混淆了) 從內存中移除。所以,iOS 裝置的使用者根本就不須要擔憂怎麼管理這些執行中或不在執行中的程序,儘管放心用、輕鬆玩就是了!瀏覽器
通常說來,全部程式進入背景後都還有5 秒的執行緩衝時間,有些程序能夠要求延長到10 分鐘(這些固然是由開發人員在設計與提交程式時決定和聲明);安全
所以,在你按下Home 鍵後,原本的程式就會退到背景,若是它有額外的背景執行做業,超過10 分鐘仍是會被iOS 停止;因此,仍是別擔憂了!服務器
可是,也有例外狀況,某些特殊類型的程式是被允許在背景中持續執行的,像是會持續在背景播放音樂的程序、GPS 程序、VOIP 程序、Newsstand 以及周邊配件附屬的程序,不過只要這些程序再也不執行動做,就會變成停止的程式,像是音樂撥完了、雜誌下載完了... 所以,使用者其實也不必太過留意這些程序。
you do not have to manage background tasks on iOS. The system handles almost every case for you and well written audio, GPS, VOIP, Newsstand and accessory apps will handle the rest.網絡
2、iOS的「多任務」發展史架構
自從出現了操做系統以來,就沒有過所謂真正的「多任務」。所謂多任務,無非是CPU速度夠快而足以支撐極短期內在多個進程內動做罷了。而所謂的「單任務」,無非是隻能讓當前任務獨享資源罷了。app
簡單來講,iOS 4 APP類型能夠分爲三種:框架
1. 保存現場。
即:按下Home鍵10秒內直接殺死進程,並釋放內存。通常說來,全部程序進入背景後都還有5 秒的執行緩衝時間,有些程序能夠要求延長到10 分鐘(這些固然是由開發人員在設計與提交程式時決定和聲明);所以,在你按下Home 鍵後,原本的程式就會退到背景,若是它有額外的背景執行做業,超過10 分鐘仍是會被iOS 停止。
2. iOS支持的「多任務」。
即:按下Home鍵轉入多任務狀態,保留在內存中,但只能系統容許的動做:好比GPS,好比VoIP,好比Streaming Music等等。
3. 真正的桌面級別的多任務。
即:只有Safari/Mail纔是真正的多任務,蘋果嫡系大都都不是。這個級別的app在後臺是沒有任何限制動做。(對於無限制動做的程序,一是會在用戶無察覺的狀況下耗光電力,二是會有安全上面的問題)。
注意:對於上述三種級別,後兩種會佔用內存的APP,也會在任意時間從內存中被砍掉,取決於你是否動用了其它app而致使內存不足。真正不會被砍掉的後臺,只有蘋果那個通知系統。
其實能夠回顧一下iOS是怎麼一步步引入如今這個機制的:
1. 剛出生,什麼都沒有,單純的單任務。
2. iPhone OS 3.0,引入通知架構。幾乎當年所有機型可用;Android晚了一年,2.2纔有此功能,到這個時候相信纔有90%上下機器用上。
3. iOS 4.0+,引入有限制的後臺多任務。
搞這麼複雜幹嗎?直接像Android一出生那樣全部app一個小虛擬機,無任何限制動做,讓根本沒有內存管理經驗和資源消耗概念的全世界最大民工羣Java程序員們寫的app任意地跑着吧!
答案只有兩個:電力,安全。安全不說,如何在保持多任務優點的同時,避免消耗過多電力,蘋果花了不少心思;而不是像webOS/Android同樣,簡單粗暴桌面級的多任務。iPhone 4甚至在硬件上面也下了苦功,利用3D層疊技術組裝A4芯片,內部元件高度集成,並把天線移至體表,增長內部電池空間。
其實至iPhone OS 3,已經足夠應付大部分應用了。用戶根本無從知道app的實際運行狀態,保存現場讓app看起來不像是剛打開同樣,通知系統又能夠在後臺默默推送消息。事實上,當前95% iOS APP依舊只有「保存現場 + 通知系統」這樣的組合,好比不少twitter客戶端,大部分人根本不會注意到它不是真正意義上的「多任務」。很震撼的事實,但確實95%的應用場景根本不須要所謂真正的「多任務」。
可是時代在變。真正須要多任務的東西出現了:電臺要stream,IM要stream,GPS要stream,多任務必須提上日程。iOS 4加進了,WP7剛剛加進了,Android/webOS打一出生就有。從本質來講,iOS/WP7/Android/webOS跑在內存中的後臺程序,惟一的區別就是,iOS/WP7限制了它能夠作的事(這就是爲何它們一出生都沒有多任務的緣由,這個架構很複雜,不是幾百行中文字能夠說明白的),而Android/webOS沒有;從技術上面來講,iOS/WP7/webOS三者架構至關,Android獨立門戶。
因而很好笑,有無限制,成了真「多任務」和僞「多任務」的區別;然後者架構更復雜,能夠套用一句「吃力不討好」。
爲何要作吃力不討好的事?答案依舊在上面,電力和安全。固然你能夠說iPhone電力也沒好到哪裏去,安全也就通常般嘛。暫且拋掉這兩樣不談,實際看看iOS有限制後臺app,和Android徹底無限制後臺app有什麼不一樣:
相信我,最終你會發現iOS上最使人詬病的app,是那些不支持標準協議的軟件平臺商們,好比騰訊。由於iOS後臺容許的動做,已經覆蓋了所有大大小小的通訊開源協議。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
3、IOS長時間後臺運行的實現代碼
一、檢查設備是否支持多任務
Apple出於性能的考慮,並非全部的iOS設備升級到iOS4之後都支持多任務,好比iPhone 3G。若是你的應用在沒有多任務特性時會出問題,爲了保持應用的健壯性,你應該對此進行判斷並處理。你能夠經過調用UIDevice對象的multitaskingSupported屬性來獲取當前設備是否支持多任務。
一般,當用戶按一下Home鍵,當前應用就會被進入後臺,應用處在後臺運行狀態一小段時間後,就會進入掛起(suspend)狀態,此時應用不會再執行任何代碼。若是系統在運行其餘應用時內存資源不足,這個掛起的應用甚至有可能被系統退出,釋放內存以供活動的應用使用。只有當用戶再次運行此應用,應用纔會從掛起狀態喚醒,代碼得以繼續執行。這就是iOS4帶來的基本的多任務特性,這個特性是通常應用默認支持的,就是說你的應用不須要任何修改就能支持基本多任務特性。二、基本多任務特性
既然是多任務你應該會在應用進入後臺時作一些處理,好比暫停一些界面的定時刷新或網絡請求。同時,或者你會在程序進入前臺時執行一些恢復操做。在你的應用的application delegate裏有2個消息用於處理這些消息:
也許你須要更多的多任務特性,好比後臺播放音樂或者是後臺進行GPS跟蹤。這會是下面介紹的內容。固然你也許不會都在application delegate處理全部的事情。若是你要在其餘對象中處理,那麼你就須要註冊系統通知了,這兩個通知分別是UIApplicationDidEnterBackgroundNotification和UIApplicationWillEnterForegroundNotification。
三、聲明你須要的後臺任務
在Info.plist中添加UIBackgroundModes鍵值,它包含一個或多個string的值,包括:
audio:在後臺提供聲音播放功能,包括音頻流和播放視頻時的聲音
location:在後臺能夠保持用戶的位置信息
voip:在後臺使用VOIP功能
前面的每一個value讓系統知道你的應用程序應該在適當的時候被喚醒。例如,一個應用程序,開始播放音樂,而後移動到後臺仍然須要執行時間,以填補音頻輸出緩衝區。添加audio鍵用來告訴系統框架,須要繼續播放音頻,而且能夠在合適的時間間隔下回調應用程序;若是應用程序不包括此項,任何音頻播放在移到後臺後將中止運行。
除了添加鍵值的方法,IOS還提供了兩種途徑使應用程序在後臺工做:
Task completion—應用程序能夠向系統申請額外的時間去完成給定的任務
Local notifications—應用程序能夠預先安排時間執行local notifications 傳遞
四、後臺播放音樂
一般,通常應用在進入後臺時,任何聲音就將會中止。這也許不是咱們所想要的。要想讓本身的應用支持後臺播放,首先要修改應用的Info.plist文件,你須要在Info.plist文件中添加UIBackgroundModes字段,該字段的值是應用支持的全部後臺模式,是一個數值類型。目前此數組能夠包含「audio」、「location」和「voip」這三個字符串常量,若是要支持後臺音樂播放,你就須要包含「audio」,其他兩個會將在後面講到。
同時,你也應該設置一下應用程序的Audio Sesstion。這個是必需的,若是不設置Audio Sesstion,應用就可能進入後臺時Audio Sesstion失活而中止播放。通常須要這麼設置就能夠了:
五、後臺GPS跟蹤
和後臺播放音樂相似,若要支持後臺GPS跟蹤,你就須要在Info.plist文件中UIBackgroundModes字段對應的數組中增長「location」字符串。
六、後臺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。