Android文檔解釋了關於保存狀態和關於在活動和片段中保存狀態的非常好的文章。
保存和恢復活動狀態有些情況下,你的活動是由於正常的應用程序的行爲摧毀了幾個方案,比如當用戶按下「後退」按鈕,或者您的活動通過調用finish()方法來標記自己的銷燬。如果活動處於停止狀態並且很長一段時間未使用活動,或者前臺活動需要更多資源,系統還可能銷燬包含活動的進程以恢復內存。
當您的活動因用戶按下「後退」或活動自行完成而被銷燬時,該活動實例的系統概念將永遠消失,因爲該行爲表示活動不再需要。但是,如果系統由於系統限制(而不是正常的應用程序行爲)而破壞了活動,那麼雖然實際的活動實例已經消失,但系統會記住它已存在,因此如果用戶導航回它,系統會創建一個新的使用一組保存的數據描述活動在銷燬時的狀態。系統用於恢復先前狀態的已保存數據稱爲實例狀態,是存儲在Bundle對象中的鍵值對的集合。
默認情況下,系統使用Bundle實例狀態來保存有關活動佈局中每個View對象的信息(例如輸入到EditText小部件中的文本值)。 因此,如果您的活動實例被銷燬並重新創建,那麼佈局的狀態將恢復到之前的狀態,而您不需要任何代碼。但是,您的活動可能包含更多想要恢復的狀態信息,例如跟蹤用戶活動進度的成員變量。
保存您的活動狀態 當你的活動開始,停止,系統調用的onSaveInstanceState()方法,因此您的活動可以保存狀態信息與鍵值對的集合。此方法的默認實現可以保存有關活動視圖層次結構狀態的瞬態信息,例如EditText小部件中的文本或ListView小部件的滾動位置。你的應用應該在onPause()方法之後和onStop()之前實現onSaveInstanceState()回調。不要在onPause()中實現此回調。
警告:您必須始終調用onSaveInstanceState()的超類實現,以便默認實現可以保存視圖層次結構的狀態。
要保存活動的其他狀態信息,必須重寫onSaveInstanceState()並將鍵值對添加到在您的活動意外銷燬的事件中保存的Bundle對象。例如:
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
注意:爲了讓Android系統以恢復您的活動的意見的狀態,每個視圖必須有一個唯一的ID,由機器人提供:id屬性。
要保存持久數據(例如用戶首選項或數據庫數據),當您的活動處於前臺時,應該採取適當的機會。如果沒有這樣的機會出現,您應該在onStop()方法中保存這些數據。
恢復您的活動狀態 當您的活動被重建後,先前被破壞,可以從捆綁恢復保存的狀態,該系統傳遞到您的活動。 onCreate()和onRestoreInstanceState()回調方法都會收到包含實例狀態信息的相同Bundle。
因爲無論系統是在創建活動的新實例還是重新創建前一個實例,都會調用onCreate()方法,您必須在嘗試讀取之前檢查狀態Bundle是否爲null。如果它爲空,那麼系統正在創建一個活動的新實例,而不是恢復之前被銷燬的實例。
例如,下面的代碼片段展示瞭如何在的onCreate()恢復了一些狀態數據:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// Probably initialize members with default values for a new instance
}
...
}
相反的onCreate()中恢復狀態,你可以選擇實施onRestoreInstanceState (),系統在onStart()方法之後調用。該系統調用onRestoreInstanceState()只如果有恢復已保存的狀態,這樣你就不會需要檢查包是否爲空:
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
注意:始終調用父類實現onRestoreInstanceState的( ),所以默認實現可以恢復視圖層次的狀態。
從你的答案,我已經編輯我的問題。謝謝。 – Orwel
查看我的第二個答案,提供更多詳細信息和代碼,以解釋什麼數據可以免費保存,哪些數據需要您編碼!如果解釋,請接受答案並投票! – JRG
我不好,你迴應我的問題。感謝JRG。 – Orwel