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