一贾虽、理解onSaveInstanceState()
當Activity是因為用戶點擊Back按鈕或者是activity通過調用finish()結束自己時,系統(tǒng)就丟失了對Activity實例的引用捷绑,因為這一行為意味著不再需要這個activity了。
然而氢妈,如果因為系統(tǒng)資源緊張而導致Activity的Destory粹污, 系統(tǒng)會在用戶回到這個Activity時有這個Activity存在過的記錄,系統(tǒng)會使用那些保存的記錄數據(描述了當Activity被Destory時的狀態(tài))來重新創(chuàng)建一個新的Activity實例首量。
那些被系統(tǒng)用來恢復之前狀態(tài)而保存的數據被叫做 "instance state" 壮吩,它是一些存放在Bundle對象中的key-value pairs。
Caution:
- onSaveInstanceState的回調用來保存狀態(tài)信息加缘。
- onRestoreInstanceState的回調用來恢復之前保存的數據鸭叙。
二、onSaveInstanceState與onRestoreInstanceState的調用時機
通常來說拣宏,跳轉到其他的activity或者是點擊Home都會導致當前的activity執(zhí)行onSaveInstanceState沈贝,因為這種情況下的activity都是有可能會被destory并且是需要保存狀態(tài)以便后續(xù)恢復使用的,而從跳轉的activity點擊back回到前一個activity勋乾,那么跳轉前的activity是執(zhí)行退棧的操作宋下,所以這種情況下是不會執(zhí)行onSaveInstanceState的嗡善,因為這個activity不可能存在需要重建的操作
- Back鍵正常退出不會調用onSaveInstanceState與onRestoreInstanceState。
D/Activity1﹕ onCreate
D/Activity1﹕ onStart
D/Activity1﹕ onResume
D/Activity1﹕ onPause
D/Activity1﹕ onStop
D/Activity1﹕ onDestroy
- Home鍵退出會調用onSaveInstanceState学歧。
D/Activity1﹕ onCreate
D/Activity1﹕ onStart
D/Activity1﹕ onResume
D/Activity1﹕ onPause
D/Activity1﹕ onSaveInstanceState
D/Activity1﹕ onStop
D/Activity1﹕ onDestroy
- Home鍵恢復會調用onRestoreInstanceState()罩引。
D/Activity1﹕ onCreate
D/Activity1﹕ onStart
D/Activity1﹕ onRestoreInstanceState
D/Activity1﹕ onResume
- 進入其他Activity會調用onSaveInstanceState。
A-B-A
D/Activity1﹕ onPause
D/Activity2﹕ onCreate
D/Activity1﹕ onSaveInstanceState
D/Activity1﹕ onStop
D/Activity1﹕ onRestart
D/Activity1﹕ onStart
D/Activity1﹕ onResume
D/Activity2﹕ onDestroy
返回A時并沒有調用onRestoreInstanceState枝笨,因為A處于后臺未被殺死喜最。
Caution: 調用關鍵在于Activity是否存在意外Destroy的風險药磺。
三、保存Activity狀態(tài)
當我們的activity開始Stop,系統(tǒng)會調用onSaveInstanceState() 届谈,Activity可以用鍵值對的集合來保存狀態(tài)信息企巢。
這個方法會默認保存Activity視圖的狀態(tài)信息哮奇,如在 EditText 組件中的文本或 ListView 的滑動位置西壮。
為了給Activity保存額外的狀態(tài)信息,你必須實現onSaveInstanceState() 并增加key-value pairs到 Bundle 對象中张咳,例如:
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, 1);
savedInstanceState.putInt(STATE_LEVEL, 2);
}
Caution:
- 必須要調用 onSaveInstanceState() 方法的父類實現帝洪,這樣默認的父類實現才能保存視圖狀態(tài)的信息。
- Activity視圖的狀態(tài)信息會默認保存脚猾,只有當需要保存額外的狀態(tài)信息時才需要調用該方法葱峡。
四、恢復Activity狀態(tài)
當Activity從Destory中重建龙助,我們可以從系統(tǒng)傳遞的Activity的Bundle中恢復保存的狀態(tài)砰奕。
onCreate() 與 onRestoreInstanceState() 回調方法都接收到了同樣的Bundle,里面包含了同樣的實例狀態(tài)信息提鸟。
- 由于 onCreate() 方法會在第一次創(chuàng)建新的Activity實例與重新創(chuàng)建之前被Destory的實例時都被調用军援,我們必須在嘗試讀取 Bundle 對象前檢測它是否為null。如果它為null称勋,系統(tǒng)則是創(chuàng)建一個新的Activity實例胸哥,而不是恢復之前被Destory的Activity。
@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
}
...
}
- 我們也可以選擇實現 onRestoreInstanceState() 赡鲜,而不是在onCreate方法里面恢復數據空厌。
onRestoreInstanceState()方法會在 onStart() 方法之后執(zhí)行. 系統(tǒng)僅僅會在存在需要恢復的狀態(tài)信息時才會調用 onRestoreInstanceState() ,因此不需要檢查 Bundle 是否為null银酬。
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);
}
Caution: 與上面保存一樣嘲更,總是需要調用onRestoreInstanceState()方法的父類實現,這樣默認的父類實現才能保存視圖狀態(tài)的信息揩瞪。
相關文章:
Android Training
Activity生命周期中的onSaveInstanceState
[2015-08]