Activity 生命週期,雖然開發android 程序有幾年了,可是不少基本東西仍是常常遺忘模糊,在此筆記白紙黑字記錄,下次記憶模糊的時候溫故知新。網上一搜索一大把,可是可能是一大堆各類日誌攪來攪去比較模糊難懂,有個別的文章就是隻知其一;不知其二比較片面,這個看似簡單可是又說清道不明,爲了更加簡單快速的理解並作筆記,我使用的是官方的示例ActivityLifecycle運行結果做爲記錄依據android
activity生命週期是應用程序層次分明運行的根本,也許不須要實現全部的生命週期方法。但瞭解每個方法的回調時機並在其中填充相應功能,使得確保app可以像用戶指望的那樣執行是頗有必要的。好比使用app的時候,不會由於有來電通話或者切換到其餘app而致使程序crash。 用戶沒有激活某個組件時不會消耗寶貴的系統資源。 離開app而且一段時間後返回,不會丟失用戶的使用進度。 設備發生屏幕旋轉時不會crash或者丟失用戶的使用進度,這些狀況都是要創建在充分的理解activity的生命週期。因此咱們須要學會如何去管理
activity
的生命週期
app
啓動程序進入到activity A 界面 而後退出該程序函數
啓動程序進入到activity A 界面,點擊Dialog按鈕彈出對話框,而後關閉對話框佈局
啓動程序進入到activity A 界面而後點擊home鍵回到桌面,而後再次點擊該程序再次回到activityA 的時候動畫
流程四很差演示,總以內存緊張的時候,好比MainActivity處於onPause和onStop狀態時,當更高優先級的apps須要內存,而此時系統內存不夠了,那麼android系統就會將MainActivity所在的進程給殺了以釋放資源。當被殺了以後又想重生,那必須得從頭開始建立。onCreate ---> onStart() ---> onResume()線程
最後當咱們在第一個 activityA中按back鍵,退出時,最終就會走到onDestory,或者在代碼中調用finish()的時候也會走到onDestroy()這一步,從而關閉Activity或者退出程序。rest
(1)記得剛開始接觸android的時候,以爲生命週期老是攪來攪去的,模模糊糊的,網上也有不少文章就是組合各類狀況打印各類日誌一大堆,看到頭大,總以爲裏面的東西規則摸不許,其實他們不少都是把簡單問題複雜化了,我剛接觸android的時候也深受其害日誌
(2)當咱們以不一樣的參照對象分別開來進行分析的時候(好比只看Activity A ),發現每個對象走的生命週期流程無非就是上面那四流程中的一種code
(3)對象多了,當咱們從把全部對象當成整來看待的時候,個他們之之間的生命週期的好像就是交錯在一塊兒(好比A啓動B時候A 調用了 onPause,而後B啓動完成了,A又調用了onStope),各類狀況記不到也說不清楚,網上就是不少這麼幹得對象
(4)其實咱們不該該把他們當成總體來看,這種觀念會讓本身陷入困境的,若是項目中(多個對象(Activity)生命週期交錯)真的須要肯定多個對象生命週期各個方法執行的前後順序的時候,那個時候來打印下日誌就一目瞭然,當具體到項目實際須要的時候再去細緻化處理比較合適,舉一個簡單的例子以下面的複合狀況
啓動程序進入到activity A,點擊Activity B,而後關閉Activity B
分析:整個過程咱們須要分開來看 :
(1)對於activity A來講生命週期是流程三
(2)對於Activity B 來講生命週期是流程一
複合狀況是在開發中常常遇到的,萬變不離宗,分開來看就能夠了,就這麼簡單,無他,可是要特別注意 Activity的四種啓動模式(standard、singleTop、singleTask、singleInstance),我如今所列舉的都是默認模式。
(1)好比正在Activity-A界面,忽然打電話過來的時候或者接收短信,這個時候彈出一個框提示,能夠理解啓動了另一個界面,固然看Activity-A界面是否覆蓋全屏,若是不覆蓋全屏該界面,那麼Activity-A界面就調用onPause(),(個人手機是彈出一個小Dialog)若是下一步取消接電話或者取消看短信回到Activity-A界面時候就調用Activity-A的onResume(),若是接電話那麼就被全屏覆蓋當那個接電話界面啓動的完成的時候Activity-A的onStop()方法,接電話結束回到Activity-A界面就會調用 onRestart()(不是生命週期方法) ——>onStart()——>onResume()
activity生命週期只有三個狀態是靜態的,這三個狀態下activity能夠存在一段比較長的時間,而其它幾個狀態會很快就切換掉,停留的時間比較短暫。
(1)Resumed:該狀態下,activity處在前臺,用戶能夠與它進行交互。(一般也被理解爲」running」 狀態)
(2)Paused:該狀態下,此時
Activity
程序失去了焦點,通常狀況
activity的部分被另一個activity所遮蓋:另外的activity來到前臺,可是半透明的,不會覆蓋整個屏幕。被暫停的activity再也不接受用戶的輸入且再也不執行任何代碼
(3)Stopped:該狀態下, activity徹底被隱藏,對用戶不可見。能夠認爲是在後臺。當stopped, activity實例與它的全部狀態信息(如成員變量等)都會被保留,但activity不能執行任何代碼,若是其餘地方須要內存,系統會銷燬這個
activity。
其它狀態 (Created與Started)都是短暫的
(1)一旦onCreate 操做完成,系統會迅速調用onStart() 與onResume()方法,咱們的activity不會在Created或者Started狀態停留,系統快速的執行那些回調函數並經過執行下一階段的回調函數移動到下一個狀態
(2)也就是說,在系統調用 onCreate(), 以後會迅速調用onStart(), 以後再迅速執行onResume()。activity在onStart()被調用後開始被用戶可見,可是 onResume()會迅速被執行使得activity停留在Resumed狀態,直到一些因素髮生變化纔會改變這個狀態。例如接收到一個來電,用戶切換到另一個activity,或者是設備屏幕關閉,以上就是基本的activity生命週期。
當系統調用activity中的onPause() ——>準備離開這個activity ——> 立刻會進入Stopped state.
(1)一般應該在onPause()回調方法裏面作如下事情,中止動畫或者是其餘正在運行的操做,那些都會致使CPU的浪費. 提交在用戶離開時期待保存的內容(例如郵件草稿). 釋放系統資源,例如broadcast receivers, sensors (好比GPS), 或者是其餘任何會影響到電量的資源。
(2)不該該使用onPause()來保存用戶改變的數據到永久存儲(File或者DB)上,咱們應該避免在onPause()時執行CPU intensive的shut-down的工做,例如寫數據到DB,由於它會致使切換到下一個activity變得緩慢,應該放到onStop(),反正儘可能減小在onPause()裏面耗時的工做量
(3)儘管onPause()方法是在onStop()以前調用,咱們應該使用onStop()來執行那些CPU intensive的shut-down操做
Activity從Paused()狀態恢復時 ——>調用onResume()方法
(1)應該實現onResume()來初始化那些在onPause方法裏面釋放掉的組件,並執行那些activity每次進入Resumed state都須要的初始化動做 (例如開始動畫與初始化那些只有在獲取用戶焦點時才須要的組件)
當activity調用onStop()方法, activity再也不可見
(1)應該釋放那些再也不須要的全部資源。一旦activity中止了,系統會在須要內存空間時摧毀它的實例(和棧結構有關,一般 back操做會致使前一個activity被銷燬)。極端狀況下,系統會直接殺死咱們的app進程,並不執行activity的onDestroy()回調方法, 所以咱們須要使用onStop()來釋放資源,從而避免內存泄漏。(這點須要注意)
(2)activity已經中止後,Activity對象會保存在內存中,並在activity resume時被從新調用。咱們不須要在恢復到Resumed state狀態前從新初始化那些被保存在內存中的組件。系統一樣保存了每個在佈局中的視圖的當前狀態,若是用戶在EditText組件中輸入了 text,它會被保存,所以不須要保存與恢復它。
當activity從Stopped狀態回到前臺時,它會調用onRestart(),系統再調用onStart()方法
(1)onStart()方法會在每次activity可見時都會被調用。onRestart()方法則是隻在activity從stopped狀態恢復時纔會被調用,所以咱們可使用它來執行一些特殊的恢復(restoration)工做,請注意以前是被stopped而不是destrory。
(2)應該使用onStart()做爲onStop()所對應方法。由於系統會在建立activity與從中止狀態重啓activity時都會調用onStart()。也就是說,咱們在onStop裏面作了哪些清除的操做,就該在 onStart裏面從新把那些清除掉的資源從新建立出來。
(3)由於咱們會在onStop方法裏面作釋放資源的操做,那麼onDestory方法則是咱們最後去清除那些可能致使內存泄漏的地方。所以須要確保那些線程都被destroyed而且全部的操做都被中止
(1)若是由於系統資源緊張而致使Activity的Destory或者旋轉屏幕時被destroyed與Recreated, 系統會在用戶回到這個Activity時有這個Activity存在過的記錄,系統會使用那些保存的記錄數據(instance state)它是一些存放在Bundle對象中的key-value pairs,系統默認使用 Bundle保存信息
(2)爲了能夠保存額外更多的數據到instance state,要重寫寫這個回調函數onSaveInstanceState(Bundle outState),系統會在Activity被異常Destory時傳遞Bundle對象,這樣咱們就能夠增長額外的信息到Bundle中並保存到系統中。若系統在Activity被Destory以後想從新建立這個Activity實例時,以前的Bundle對象會(系統)被傳遞到你咱們activity的
(3)Activity開始stop,系統會調用 onSaveInstanceState(Bundle outState) ,Activity能夠用鍵值對的集合來保存狀態信息。這個方法會默認保存Activity視圖的狀態信息,如在 EditText組件中的文本或 ListView 的滑動位置
(1)當Activity從Destory中重建,咱們能夠從系統傳遞的Activity的Bundle中恢復保存的狀態。 onCreate() 與 onRestoreInstanceState() 回調方法都接收到了一樣的Bundle,裏面包含了一樣的實例狀態信息。
(2)因爲 onCreate() 方法會在第一次建立新的Activity實例與從新建立以前被Destory的實例時都被調用,咱們必須在嘗試讀取 Bundle 對象前檢測它是否爲null。若是它爲null,系統則是建立一個新的Activity實例,而不是恢復以前被Destory的Activity。
(3)也能夠選擇實現 onRestoreInstanceState() ,而不是在onCreate方法裏面恢復數據。 onRestoreInstanceState()方法會在 onStart() 方法以後執行. 系統僅僅會在存在須要恢復的狀態信息時纔會調用 onRestoreInstanceState() ,所以不須要檢查 Bundle 是否爲null。