轉 https://www.jianshu.com/p/27181e2e32d2
背景
如果系統由於系統約束(而不是正常的應用程序行為)而破壞了Activity,那么盡管實際 Activity實例已經消失,但是系統還是會記住它已經存在,這樣如果用戶導航回到它,系統會創建一個新的實例的Activity使用一組保存的數據來描述Activity在被銷毀時的狀態。系統用於恢復以前狀態的已保存數據稱為“實例狀態”,是存儲在Bundle對象中的鍵值對的集合。
解決
onSaveInstanceState()和onRestoreInstanceState()就是這樣的背景下大展身手了。
注意
1、如果是用戶自動按下返回鍵,或程序調用finish()退出程序,是不會觸發onSaveInstanceState()和onRestoreInstanceState()的。
2、每次用戶旋轉屏幕時,您的Activity將被破壞並重新創建。當屏幕改變方向時,系統會破壞並重新創建前台Activity,因為屏幕配置已更改,您的Activity可能需要加載替代資源(例如布局)。即會執行onSaveInstanceState()和onRestoreInstanceState()的。
介紹
默認情況下,系統使用Bundle實例狀態來保存有關View中Activity布局每個對象的信息(例如輸入到EditText對象中的文本值)。因此,如果您的Activity實例被銷毀並重新創建,則布局狀態會自動恢復到之前的狀態。但是,您的Activity可能包含更多要恢復的狀態信息,例如跟蹤Activity中用戶進度的成員變量。
為了讓您為Activity添加額外的數據到已保存的實例狀態,Activity生命周期中還有一個額外的回調方法,這些回調方法在前面的課程中沒有顯示。該方法是onSaveInstanceState(),系統在用戶離開Activity時調用它。當系統調用此方法時,它將傳遞Bundle將在您的Activity意外銷毀的事件中保存的對象,以便您可以向其中添加其他信息。然后,如果系統在被銷毀之后必須重新創建Activity實例,它會將相同的Bundle對象傳遞給您的Activity的onRestoreInstanceState()方法以及您的onCreate() 方法。

如上圖所示:
當系統開始停止您的Activity時,它會調用onSaveInstanceState()(1),以便您可以指定要保存的其他狀態數據,以防Activity必須重新創建實例。如果Activity被破壞並且必須重新創建相同的實例,則系統將(1)中定義的狀態數據傳遞給onCreate()方法(2)和onRestoreInstanceState()方法(3)。
保存你的Activity狀態
當您的Activity開始停止時,系統會調用,onSaveInstanceState()以便您的Activity可以使用一組鍵值對來保存狀態信息。此方法的默認實現保存有關Activity視圖層次結構狀態的信息,例如EditText小部件中的文本或ListView的滾動位置。
為了保存Activity的附加狀態信息,您必須實現onSaveInstanceState()並向對象添加鍵值對Bundle。例如:
static final String STATE_SCORE = "playerScore"; static final String STATE_LEVEL = "playerLevel"; ...
恢復您的Activity狀態
當您的Activity在之前被破壞后重新創建時,您可以從Bundle系統通過您的Activity中恢復您的保存狀態。這兩個方法onCreate()和onRestoreInstanceState()回調方法都會收到Bundle包含實例狀態信息的相同方法。
因為onCreate()調用該方法是否系統正在創建一個新的Activity實例或重新創建一個以前的實例,所以您必須Bundle在嘗試讀取之前檢查該狀態是否為空。如果它為空,那么系統正在創建一個Activity的新實例,而不是恢復之前被銷毀的實例。
例如,下面是如何恢復一些狀態數據onCreate():
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 記得總是調用父類 // 檢查是否正在重新創建一個以前銷毀的實例 if (savedInstanceState != null) { // 從已保存狀態恢復成員的值 mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); } else { // 可能初始化一個新實例的默認值的成員 } ... }
onCreate()您可以選擇執行onRestoreInstanceState(),而不是在系統調用onStart()方法之后恢復狀態。系統onRestoreInstanceState()只有在存在保存狀態的情況下才會恢復,因此您不需要檢查是否Bundle為空:
public void onRestoreInstanceState(Bundle savedInstanceState) { // 總是調用超類,以便它可以恢復視圖層次超級 super.onRestoreInstanceState(savedInstanceState); // 從已保存的實例中恢復狀態成員 mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); }