生命週期方法中,有三對是相互對應的,即 onCreate 與 onDestroy、onStart 與 onStop、onPause 與 onResume。一些初始化工做例如初始化相機、初始化播放器、開始播放、註冊 Receiver、監聽 GPS 座標變化、監聽 Bus 事件等,在哪裏開始並無必定之規,應當根據具體的業務須要在 onCreate / onStart / onResume 中選擇最合適的,但必定要在其相對應的生命週期方法中執行相反的操做或者釋放資源,才能保證在各類狀態都不會出現問題。html
與上述生命週期方法相對應,Activity 有這些狀態: Created / Started / Resumed / Paused / Stopped / Destroyed 。其中 Created / Started 是瞬間狀態,由於調用 onCreate 以後馬上會調用 onStart,而 onStart 以後也必定會當即調用 onResume。Resumed / Paused / Stopped 是持久狀態,例如 Activity 在前臺且得到焦點,此時是 Resumed 狀態;可見但未得到焦點,例如被一個 dialog 樣式的 Activity 覆蓋、多窗口模式下其它窗口得到了焦點,此時就是 Paused 狀態;而 Activity 被徹底覆蓋且未銷燬的狀況之下,會一直停留在 Stopped 狀態。android
進入:onCreate -> onStart -> onResume
按 Home 鍵或者被新的 Activity 徹底覆蓋:onPause -> onStop
退出:onPause -> onStop -> onDestroy數據庫
Activity A 啓動了 Activity B(B 不是 dialog 樣式):
A.onPause -> B.onCreate -> B.onStart -> B.onResume -> A.onStop
從 Activity B 再退回 Activity A:
B.onPause -> A.onRestart -> A.onStart -> A.onResume -> B.onStop -> B.onDestroy網絡
系統配置發生變化時,Activity 會被銷燬並重建,由於 Android 系統中的資源都是和系統配置相關的,例如咱們的 layout 可能取決於設備是橫屏仍是豎屏,String 取決於當前系統語言等,重建 Activity 會根據新的系統配置加載合適的資源。
銷燬時 Activity 的 onPause、onStop、onDestroy 方法會依次被調用,同時系統會調用 onSaveInstanceState 方法保存當前 Activity 的狀態到 Bundle 對象中;重建時系統會調用 onRestoreInstanceState 方法並將以前保存的 Bundle 對象傳遞給 onCreate 方法和 onRestoreInstanceState 方法。app
當系統內存不足時,低優先級的 Activity 會被系統殺死,優先級順序從高到低以下:異步
當系統內存不足時,會按照由低到高的優先級順序去殺掉目標 Activity 所在進程,並在後續經過 onSaveInstanceState 和 onRestoreInstanceState 來存儲和恢復數據。沒有運行四大組件的進程優先級最低,很容易被系統殺死,所以後臺工做不該當脫離四大組件單獨運行,能夠放到 Service 中。ide
Android P 以前 onSaveInstanceState 方法會在 onStop 以前被調用,有可能在 onPause 以前也有可能在 onPause 以後;Android P 及以後的的版本中 onSaveInstanceState 方法會在 onStop 以後被調用。
onRestoreInstanceState 方法會在 onStart 方法以後調用,其傳入的 Bundle 對象必定不是 null,恢復的工做也能夠放到 onCreate 方法中。 onSaveInstanceState 方法和 onRestoreInstanceState 方法的默認實現會保存和恢復當前界面中全部 View 的狀態,不須要作特殊處理。
onSaveInstanceState 方法會在 Activity 須要銷燬重建,或者被切換到後臺時被調用,例如切換橫豎屏、鎖屏、被新的 Activity 徹底遮住、按 Home 鍵等。但這兩個方法不必定是成對的被調用的,onRestoreInstanceState 被調用的前提是,Activity 確實被系統銷燬了而且在重建,大部分狀況下調用 onSaveInstanceState 並不意味着 Activity 真的會被銷燬,只是爲了保險而已。動畫
這是個很古老的問題。兩者最明顯的區別是是否可見,若是 Activity 失去焦點就會調用 onPause,但只有 Activity 徹底不可見時纔會調用 onStop。只調用 onPause 不調用 onStop 情景能夠舉下面兩個例子:ui
這個問題有些麻煩,Android 官方文檔實際上是存在自相矛盾的,咱們來分析一下:
Understand the Activity Lifecycle 中有這樣一段話:this
onPause() execution is very brief, and does not necessarily afford enough time to perform save operations. For this reason, you should not use onPause() to save application or user data, make network calls, or execute database transactions; such work may not complete before the method completes. Instead, you should perform heavy-load shutdown operations during onStop().
大意是講,onPause 方法應該快速結束,不該該在其中進行耗時操做,例如保存用戶數據、發起網絡請求、執行數據庫事物等,這些重量級的工做應該放到 onStop 當中。
然而 Activity 類的文檔中又有相反的說法:
onPause() is where you deal with the user pausing active interaction with the activity. Any changes made by the user should at this point be committed (usually to the ContentProvider holding the data). In this state the activity is still visible on screen. Note the "Killable" column in the above table -- for those methods that are marked as being killable, after that method returns the process hosting the activity may be killed by the system at any time without another line of its code being executed. Because of this, you should use the onPause() method to write any persistent data (such as user edits) to storage.
就是說 Activity 在執行完 onPause 方法後會進入」Killable「狀態,系統有可能在不執行 onStop 的狀況下直接殺掉進程,若是沒有在 onPause 中保存數據,就沒有機會了。然而 Android 3.0 以後有了細微的變化,系統能夠保證殺掉進程時 onStop 也會被調用:
Be aware that these semantics will change slightly between applications targeting platforms starting with Build.VERSION_CODES.HONEYCOMB vs. those targeting prior platforms. Starting with Honeycomb, an application is not in the killable state until its onStop() has returned. This impacts when onSaveInstanceState(android.os.Bundle) may be called (it may be safely called after onPause()) and allows an application to safely wait until onStop() to save persistent state.
綜合上面的觀點,若是不考慮兼容 3.0 以前的系統(市面已經不多了),在 onPause 或者 onStop 中保存數據其實均可以的,都可以獲得保證。可是 onPause 方法不適合執行太耗時的操做,由於不管是開啓新的 Activity 仍是退出當前 Activity,都要等到 onPause 方法執行完成後纔會看到新的界面,應當儘可能爲其減輕負擔,因此除非必定要在 onPause 中完成的部分,保存數據應當放到 onStop 中。
固然這不是徹底絕對的,也要結合具體業務需求。舉個例子,好比有兩個 Activity A 和 B,用戶能夠在 A 中設置參數,而且這個設置項要保存到 Preference 中,而 B 須要從 Preference 中讀取這個設置項並顯示出來。若是 A 在 onStop 方法中保存數據,當用戶從 A 啓動 B 時就會出問題:因爲 A 的 onStop 方法調用其實在 B 初始化以後,此時 B 是沒法獲取到這個最新值的,這種狀況 A 只能在 onPause 方法中保存數據。
另外,在 Activity 文檔中 Saving Persistent State 這一節,官方建議使用「edit in place」的方式來保存數據,這種策略和 AndroidStudio 保存文件的策略類似,即數據發生改變後要隨時保存,這樣哪怕發生了 Crash 或者手機斷電之類的極端狀況,也能夠保證數據不會丟失,比在 onPause 或者 onStop 中保存數據要更靠譜。
onSaveInstanceState 和 onRestoreInstanceState 並非 Activity 的生命週期方法,咱們在上面那張生命週期流程圖中也沒有看到它們。onPause 和 onStop 是 Activity 中止或退出時會調用的方法,所以咱們通常會在其中作保存數據的操做,也就是將數據持久化到磁盤。onSaveInstanceState 方法只有系統須要重建 Activity 時,例如退到後臺、系統設置發生變化、系統內存不足殺掉 Activity 時纔會被調用,若是是正常的 finish 流程則不會被調用。onSaveInstanceState 雖然也是保存數據,但它的目標並非將數據持久化,而是將一些和 UI、當前狀態相關的變量等交給系統來保存,若是這個 Activity 還須要再恢復,就能夠用這些數據還原現場。
總結一下,調用場景不一樣,調用的目的也不一樣,因此說它們並無什麼必然的聯繫。
標準啓動模式,每一個 Intent 從新生成一個實例。
複用棧頂模式,若是已有相同 Activity 實例且位於棧頂,則不會從新生成實例,只會調用棧頂 Activity 的 onNewIntent() 方法;若是已有相同 Activity 且不在棧頂,仍是會生成新實例,同 standard 模式。
首先根據指定的 taskAffinity 查找任務,若是存在就在已有任務中啓動,不然啓動新的任務;若是在已有任務中啓動,會在任務中查找當前 Activity 的實例,找到就將其上面的全部 Activity 結束並調用該實例的 onNewIntent() 方法,不然建立新的實例。
單獨佔用一個任務,再次啓動時複用已有任務和實例。該 Activity 啓動的 Activity 會運行在其它任務中,和 singleTask 狀況相似。
Understand the Activity Lifecycle | Android Developers
Activity | Android Developers
任務和返回棧 | Android Developers
《Android 開發藝術探索》第1章
Android中Activity四種啓動模式和taskAffinity屬性詳解 - 張紀剛的博客 - CSDN博客
解開Android應用程序組件Activity的"singleTask"之謎 - 老羅的Android之旅 - CSDN博客