
iOS應(yīng)用的生命周期,程序是在前臺還是后臺運行,是活躍還是掛起狀態(tài),對于開發(fā)者來說是很重要的,開發(fā)者需要監(jiān)聽App的當(dāng)前狀態(tài)的改變,以便做出相應(yīng)的處理。
一個應(yīng)用程序有五種狀態(tài)
首先,我們了解一下一個iOS應(yīng)用程序有哪幾種狀態(tài)。
-
Not running未運行 ,程序未啟動。 -
Inactive未激活 ,程序在前臺運行,但沒有接收到任何事件。在程序沒有事件需要處理時停留在這個狀態(tài),相當(dāng)于程序休眠。 -
Active激活,程序在前臺運行而且接收到了事件,App接下來會處理這個事件。一個應(yīng)用程序大部分時間都處于這個狀態(tài)。 -
Backgroud后臺,程序在后臺而且能執(zhí)行代碼,大多數(shù)程序只能短暫停留這個狀態(tài),馬上進入Suspended狀態(tài)。 -
Suspended掛起,程序在后臺不能執(zhí)行代碼。但程序不會被馬上殺死,當(dāng)系統(tǒng)內(nèi)存不足時,在這個狀態(tài)的程序占用的內(nèi)存優(yōu)先被回收。
下圖是各個狀態(tài)的轉(zhuǎn)換圖

切換狀態(tài)時的回調(diào)
在發(fā)生狀態(tài)切換時,UIApplication都會調(diào)用當(dāng)前代理對象對應(yīng)的方法來通知App狀態(tài)的改變。
//程序即將啟動完成
-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
return YES;
}
//程序啟動完成
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return YES;
}
//程序切換到Active狀態(tài)
-(void)applicationDidBecomeActive:(UIApplication *)application{
}
//程序被來電或低電量中斷,或者程序即將進入后臺
-(void)applicationWillResignActive:(UIApplication *)application{
}
//程序進入后臺
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
//程序進入前臺
-(void)applicationWillEnterForeground:(UIApplication *)application{
}
//程序?qū)⒁K止
-(void)applicationWillTerminate:(UIApplication *)application{
}
有了這些回調(diào),程序員就能很容易地捕捉應(yīng)用程序當(dāng)前的狀態(tài),從而做出處理。
值得一提的是,在實際開發(fā)中,將所有的程序狀態(tài)都放在AppDelegate中處理,并不是很方便。所以,也可以通過監(jiān)聽通知,獲取到當(dāng)前的程序狀態(tài)。
UIKIT_EXTERN NSNotificationName const UIApplicationDidEnterBackgroundNotification NS_AVAILABLE_IOS(4_0);
UIKIT_EXTERN NSNotificationName const UIApplicationWillEnterForegroundNotification NS_AVAILABLE_IOS(4_0);
UIKIT_EXTERN NSNotificationName const UIApplicationDidFinishLaunchingNotification;
UIKIT_EXTERN NSNotificationName const UIApplicationDidBecomeActiveNotification;
UIKIT_EXTERN NSNotificationName const UIApplicationWillResignActiveNotification;
UIKIT_EXTERN NSNotificationName const UIApplicationWillTerminateNotification;
當(dāng)App狀態(tài)變化時,這些代理的調(diào)用順序是怎樣的呢?
- App啟動

App啟動時,首先由Not running狀態(tài)切換到Inactive狀態(tài),此時調(diào)用application:willFinishLaunchingWithOptions:代理。加載完成后,調(diào)用application:didFinishLaunchingWithOptions:代理,最后由Inactive狀態(tài)切換到Active狀態(tài),此時調(diào)用applicationDidBecomeActive:代理。
- App無事件響應(yīng)

由Active狀態(tài)切換到Inactive狀態(tài),此時調(diào)用applicationWillResignActive:代理。
- 切換App

當(dāng)切換到另一個App時,由狀態(tài)Active切換到Inactive,此時調(diào)用applicationWillResignActive:代理;然后從Inactive狀態(tài)切換到running(background)狀態(tài),此時調(diào)用applicationDidEnterBackground:代理。
- 鎖屏

當(dāng)手機鎖屏?xí)r,由狀態(tài)Active切換到Inactive,此時調(diào)用applicationWillResignActive:代理,然后再由Inactive狀態(tài)切換到running(background)狀態(tài),此時調(diào)用applicationDidEnterBackground:代理。
- App響應(yīng)中斷

當(dāng)一個基于警告式的中斷發(fā)生時,比如有電話打進來了,程序會臨時進入Inactive狀態(tài),這用戶可以選擇如何處理這個中斷。接著會調(diào)用applicationWillResignActive:方法,當(dāng)中斷來臨時,你需要在這個方法中,停止timer或者周期性任務(wù)、停止視頻,音樂播放、停止游戲運行。當(dāng)程序回到Active狀態(tài) , applicationDidBecomeActive:會調(diào)用代理,恢復(fù)停止的操作。
- App轉(zhuǎn)到后臺運行

首先調(diào)用applicationWillResignActive:代理,程序即將進入后臺運行,接著調(diào)用applicationDidEnterBackground:代理,此時程序為Background狀態(tài),系統(tǒng)允許程序繼續(xù)運行一段時間,然后程序進入Suspended狀態(tài)。
- App轉(zhuǎn)到前臺運行

系統(tǒng)喚醒程序,調(diào)用applicationWillEnterForeground:代理,程序從Background狀態(tài)改為Active狀態(tài),接著調(diào)用applicationDidBecomeActive:代理。當(dāng)app處于掛起狀態(tài)時,它是不能執(zhí)行任何代碼的。因此它不能處理在掛起期間發(fā)過來的通知,比如方向改變,時間改變,設(shè)置的改變還有其他影響程序展現(xiàn)的或狀態(tài)的通知。在程序返回后臺或前臺時,程序要正確的處理這些通知。
- App終止
當(dāng)App被系統(tǒng)終止(如內(nèi)存不足、Crash)或者用戶自行終止。系統(tǒng)會在應(yīng)用程序終止之前調(diào)用applicationWillTerminate:代理,來保存用戶的一些重要數(shù)據(jù)以便下次啟動時恢復(fù)到app原來的狀態(tài)。
參考文章: