在UIApplication的狀態(tài)轉(zhuǎn)換過程中根據(jù)不同的情況會發(fā)送不同的Delegate消息,下面主要描述UIApplication狀態(tài)轉(zhuǎn)換的各種情況以及發(fā)送哪些Delegate消息及消息的順。
首先將涉及到UIApplication狀態(tài)轉(zhuǎn)換的Delegate消息編號如下:
1、application:didFinishLaunchingWithOptions:
2、application:openURL:sourceApplication:annotation:
4、applicationWillResignActive:
5、applicationDidEnterBackground:
6、applicationWillEnterForeground:
則對于下面各種操作Delegate消息的發(fā)送順序?yàn)?/p>
1、通過SpringBoard第一次啟動,消息順序?yàn)?-3
2、通過URL第一次啟動,消息順序?yàn)?-2-3
3、運(yùn)行過程中按Home鍵,消息順序?yàn)?4-5
? ? 若為iOS4.0以下或者Info.plist中設(shè)置了UIApplicationExitsOnSuspend,則繼續(xù)發(fā)送消息7,然后程序終止;
? ? 否則根據(jù)程序設(shè)置進(jìn)入Background運(yùn)行模式或者Suspend狀態(tài)。
4、運(yùn)行過程中按鎖屏鍵,消息順序與按Home鍵相同,區(qū)別在于此時會關(guān)閉所有網(wǎng)絡(luò)連接(iOS5.0+)
5、運(yùn)行過程中被短信/電話等中斷,則發(fā)送消息 4
? ? 若用戶選擇短信/電話,則發(fā)送消息 5,后續(xù)流程與按Home鍵相同。
? ? 若用戶忽略短信/電話,則發(fā)送消息 3,回到Foreground運(yùn)行狀態(tài)。
6、運(yùn)行過程中雙擊Home鍵顯示任務(wù)切換器,會發(fā)送消息 4
? ? 若選擇其他程序或者單擊Home鍵返回到SpringBoard,則發(fā)送消息 5,后續(xù)流程與按Home鍵相同。
? ? 若再次雙擊Home鍵返回APP,則發(fā)送消息 3,回到Foreground運(yùn)行狀態(tài)。
7、通過SpringBoard或者任務(wù)切換器再次啟動時,消息順序?yàn)?-3.
從后臺重新返回前臺的轉(zhuǎn)換過程中,即6與3消息的中間,在5.1的模擬器中顯示的是Default.png,但在真實(shí)設(shè)備上顯示的進(jìn)入后臺的screenshot。
8、通過URL再次啟動時,消息順序6-2-3.
9、程序在Background/Suspend狀態(tài)時,用戶雙擊Home鍵。
? ? 如果程序同時啟用了Required background modes,比如App plays audio,此時如果程序home到后臺,并且正在播放音樂,此時用戶手動/自動中止程序是會觸發(fā)applicationWillTerminate:的。如果你使用了后臺任務(wù)處理beginBackgroundTaskWithExpirationHandler也是同樣道理。
? ? 如果程序在后臺時app并沒有后臺任務(wù)執(zhí)行,則會進(jìn)入Suspend,此時手動/自動中止程序則不會觸發(fā)applicationWillTerminate:的。
10、當(dāng)程序在Suspend狀態(tài)時,若內(nèi)存緊張,系統(tǒng)也會將程序立即終止以回收內(nèi)存,此時也不會有任何消息發(fā)送。
總結(jié):
1、程序在Suspend狀態(tài)被中止時不會觸發(fā)applicationWillTerminate:
2、程序在Background狀態(tài)并且有后臺任務(wù)執(zhí)行時被中止則會觸發(fā)applicationWillTerminate:
所以對于需要在程序退出時保存數(shù)據(jù),狀態(tài)等的需求,最好在applicationDidEnterBackground:以及applicationWillTerminate:例都做處理。
二.狀態(tài)轉(zhuǎn)換廣播通知
以上消息只會發(fā)給AppDelegate,如果想在UIViewController中監(jiān)聽UIApplication的狀態(tài)變化,可以監(jiān)聽以下通知
UIApplicationDidBecomeActiveNotification(iOS2.0+)
UIApplicationDidEnterBackgroundNotification(iOS4.0+)
UIApplicationWillEnterForegroundNotification(iOS4.0+)
UIApplicationWillResignActiveNotification(iOS2.0+)
UIApplicationWillTerminateNotification(iOS2.0+)
使用下面代碼可獲取當(dāng)前Application的運(yùn)行狀態(tài)
[UIApplication sharedApplication].applicationState
狀態(tài)包括UIApplicationStateActive? ?UIApplicationStateInactive? ?UIApplicationStateBackground
當(dāng)APP在某個UIViewController顯示時進(jìn)入后臺或者從后臺返回到前臺時,并不會調(diào)用viewWillDisappear:,viewDidDisappear:,viewWillAppear:,viewDidAppear:系列方法,但此時的視圖確實(shí)發(fā)生Disappear以及Appear的事件。
如果在這種情況下需要做些處理的話,可以在viewDidAppear:中注冊對上述通知的監(jiān)聽,在接收到APP進(jìn)入后臺以及從后臺返回時通知時做相應(yīng)的處理。在viewWillDisappear:中我們可以取消對上述通知的監(jiān)聽,因?yàn)槿绻?dāng)前顯示的不是此視圖,就沒有Disappear以及Appear的事件發(fā)生,也就不需要在前后臺切換時做任何特殊處理。
需要這樣做的情況有:
在View Appear時需要重新請求數(shù)據(jù)時;
當(dāng)視圖包含動畫,在進(jìn)入后臺模式時動畫會停止,返回到前臺時需要重新啟動動畫時;
三.CoreLocation 更新消息
如果使用CoreLocation,當(dāng)程序運(yùn)行在Background模式下出現(xiàn)位置更新時,還有特殊的消息需要處理,見CoreLocation Background Update Messaging。