我們平常使用APP時,一般人都會知道有:簡單的正在使用狀態;通過home鍵等方式離開應用,但是不關閉應用,即後臺狀態;以及調出後臺程式管理後向上滑動將應用“殺死”,三種狀態。而我們開發者則會了解得更深便於進行開發工作。還有更多更深的知識還需要在未來進行探索後總結。而接下來將對當前初級階段對APP的生命週期所學知識進行總結。
應用程式的五種狀態
1. Not running:
應用還沒有啟動,或者應用正在執行但是途中被系統停止。
2. Inactive:
當前應用正在前臺執行,但是並不接收事件(當前或許正在執行其它程式碼)。一般每當應用要從一個狀態切換到另一個不同的狀態時,中途過渡會短暫停留在此狀態。例如使用者鎖屏或者接到通知去響應別的事件的時候。
3. Active:
當前應用正在前臺執行,並且接收事件。這是應用正在前臺執行時所處的正常狀態。
4. Background:
應用處在後臺,並且還在執行程式碼。大多數將要進入Suspended狀態的應用,會先短暫進入此狀態。除了一些經過特殊的請求後可以長期處於此狀態的應用。存在一些啟動後會直接進入background狀態的應用。
5. Suspended:
應用處在後臺,並且已停止執行程式碼。系統會自動把程式變成這個狀態而且不會發出通知。當掛起時,程式還是停留在記憶體中的,當系統記憶體低時,系統就把掛起的程式清除掉,為前臺程式提供更多的記憶體。
iOS程式執行過程
可由下圖做一個總覽:
其中,監聽系統事件的方法在AppDelegate.m檔案中,裡面的幾個方法代理的回撥分別解釋為:
// 告訴代理啟動基本完成程式準備開始執行
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
複製程式碼
// 當應用程式將要入非活動狀態執行,在此期間,應用程式不接收訊息或事件,比如打來電話
- (void)applicationWillResignActive:(UIApplication *)application
複製程式碼
// 當應用程式入活動狀態執行,此方法跟上面那個方法相反
- (void)applicationDidBecomeActive:(UIApplication *)application
複製程式碼
// 當程式被推送到後臺的時候呼叫。所以要設定後臺繼續執行,則在這個函式裡面設定即可
- (void)applicationDidEnterBackground:(UIApplication *)application
複製程式碼
// 當程式從後臺將要重新回到前臺時候呼叫,此方法跟上面的那個方法相反
- (void)applicationWillEnterForeground:(UIApplication *)application
複製程式碼
// 當程式將要退出是被呼叫,通常是用來儲存資料和一些退出前的清理工作
- (void)applicationWillTerminate:(UIApplication *)application
複製程式碼
在此新增NSLog列印進行相關操作時執行的方法
各個操作時方法執行順序均為從上到下。
分為啟動程式時:
function:-[AppDelegate application:didFinishLaunchingWithOptions:] line:25 content:-[AppDelegate application:didFinishLaunchingWithOptions:]
複製程式碼
function:-[AppDelegate applicationDidBecomeActive:] line:52 content:-[AppDelegate applicationDidBecomeActive:]
複製程式碼
點選home鍵時:
function:-[AppDelegate applicationWillResignActive:] line:33 content:-[AppDelegate applicationWillResignActive:]
複製程式碼
function:-[AppDelegate applicationDidEnterBackground:] line:40 content:-[AppDelegate applicationDidEnterBackground:]
複製程式碼
雙擊home鍵或點選圖示再次開啟程式時:
function:-[AppDelegate applicationWillEnterForeground:] line:46 content:-[AppDelegate applicationWillEnterForeground:]
複製程式碼
function:-[AppDelegate applicationDidBecomeActive:] line:52 content:-[AppDelegate applicationDidBecomeActive:]
複製程式碼
瞭解了APP執行中的幾種狀態和週期,我們可以對一些狀況進行響應的優化和處理。
例如當出現突然來電話了等導致程式臨時進入Inactive狀態時,我們可以在applicationWillResignActive:
方法中:
- 停止timer 和其他週期性的任務
- 停止任何正在執行的請求
- 暫停視訊的播放
- 如果是遊戲那就暫停它
- 減少OpenGL ES的幀率
- 掛起任何分發的佇列和不重要的操作佇列(你可以繼續處理網路請求或其他時間敏感的後臺任務)。
當程式進入後臺時:
應該實現:
- 儲存使用者資料或狀態資訊,所有沒寫到磁碟的檔案或資訊,在進入後臺時,最後都寫到磁碟去,因為程式可能在後臺被殺死
- 釋放盡可能釋放的記憶體
在後臺時,每個應用程式都應該釋放最大的記憶體。系統會盡可能保證多的應用程式在後臺執行。所以後臺會為了減少程式佔用的記憶體自動回收一些系統幫助你開闢的記憶體,如:
- 系統回收Core Animation的後備儲存
- 去掉任何系統引用的快取圖片
- 去掉系統管理資料快取強引用
我們也可以做一些努力:
把一些物件的強引用去掉,這樣編譯器就可以回收這些記憶體:
- 圖片物件
- 你可以重新載入的 大的視訊或資料檔案
- 任何沒用而且可以輕易建立的物件
程式終止時:
APP終止時,系統會呼叫applicationWillTerminate:
方法,我們可以在其中進行一些儲存資料或狀態或一些清理的工作。方法中的這些工作會有最多5秒的時間限制,如果超過時間還有未完成的任務,你的程式就會被終止而且從記憶體中清除。
而像進入後臺和程式終止狀態,如果還需要長時間的執行任務,可以呼叫 beginBackgroundTaskWithExpirationHandler
方法去請求後臺執行時間和啟動執行緒來執行長時間執行的任務。