存在一些情況,由於普通的程序行為,你的activity會被銷毀,比如,當用戶點擊Back按鈕,或者自己調用finish()方法。另外,如果activity被停止了並且很久沒被使用,或者前台的系統需要更多的資源,系統也可能會銷毀你的activity。
當你的activity是因為按Back鍵或者自己結束的,那麼系統認為這個activity實例已經是不需要了,因為你的行為明確指出了你要銷毀它。然而,如果系統是強制銷毀你的activity的話,雖然activity實例已經沒有了,不過系統能夠記住它的存在,當用戶從新回到這個程序時,系統會使用activity被銷毀時保存的狀態重新創建一個activity實例。這個系統用來恢復先前狀態的保存數據被稱為“實例狀態”,是一些key-value的集合保存在Bundle對象中。
警告:當用戶旋轉屏幕時,你的activity會被銷毀並且重新創建。因為屏幕配置已經改變,你的activity可能也需要加載另外一些可選擇的資源(比如布局)。
默認情況下,系統使用Bundle實例狀態保存布局中每個View對象的信息(比如EditText對象中的文本值)。所以,如果你的activity對象被銷毀和重新創建時,布局狀態會重新恢復到先前的狀態。不管怎樣,你的activity可能有很多需要恢復的狀態信息,比如追蹤用戶進程的成員變量。
為了你能夠保存一些額外的數據到實例狀態中,這裡提供了一個額外的生命周期回調函數,它沒有在前面課程的圖例中顯示出來。這個函數叫onSaveInstanceState(),當用戶離開activity時系統會調用它。當你的activity被意外銷毀時,系統會調用這個函數,函數的Bundle對象會被保存下來,所以你可以添加額外的信息給這個Bundle。然後,如果系統必須重啟這個被銷毀的activity,它就傳遞相同的Bundle對象給activity的onRestoreInstanceState()方法和onCreate()方法。
圖解:當系統開始停止你的activity,它呼叫onSaveInstanceState()(1)方法,因此你可以保存指定的附加狀態數據。如果activity被銷毀了,然後相同的實例要被重新創建,系統傳遞定義在(1)的狀態給onCreate()(2)和onRestoreInsatanceState()(3)。
保存你的activity狀態
當你的activity開始停止,系統就調用onSaveInstanceState(),你可以在這個函數中使用key-value對的集合保存信息。默認函數實現了保存activity的view狀態,比如EditText的文本,或者ListView的滾動條位置。
為了保存附加信息,你必須實現onSaveInstanceState()方法,添加key-value對到Bundle對象中,例如:
警告:通常需要在onSaveInstanceState()實現中調用它的父類方法,以便能夠實現保存view的信息。
恢復你的activity狀態
如果你的activity在它被銷毀後重啟,你可以從系統傳遞給你的Bundle中恢復保存的狀態,onCreate()和onRestoreInstanceState()都可以接受到相同的包含實例狀態信息的Bundle。
因為onCreate()函數在系統創建一個新的activity實例或者重新創建前一個activity時都會調用,所以你必須在讀取Bundle前檢查它是否為空,如果是空的,那麼系統是創建一個新的實例,如果不是,那麼就恢復前一個被銷毀的activity。
例如,這裡是onCreate()方法中實現恢復數據:
你也可以選擇在onRestoreInstranceState()方法中實現,當系統調用完onStart()函數後會調用onRestoreInstranceState(),不過僅僅是當有狀態需要恢復時才會調用,所以你不需要檢查Bundle是否為空:
警告:通常需要調用onRestoreInstanceState()的父類方法,以便能恢復默認的視圖狀態。