本節書摘來自異步社群《android 開發入門與實戰(第二版)》一書中的第6章,第6.7節如何儲存和恢複activity狀态,作者eoe移動開發者社群 組編 , 姚尚朗 , 靳岩,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
6.7 如何儲存和恢複activity狀态
android 開發入門與實戰(第二版)
之前我們提到了activity的生命周期,也稍微了解了onpause和onstop方法,在調用了這兩個方法後,activity暫停或者停止(界面可能直接被覆寫了),但是這個activity的執行個體仍然存在于記憶體中,并且它的資訊和狀态資料都不會銷毀,當activity重新回到前台後,所有的這些資訊和狀态又會回到和以前一樣。
但是,如果系統在記憶體不足的情況下調用了onpause或onstop方法,activity可能會被系統銷毀,這個時候,記憶體中是不會存在activity執行個體的,如果該activity再次回到前台,之前的資訊和狀态可能無法儲存,頁面也就無法根據這些資訊和狀态回到原來的樣子。為了避免這種情況,activity中提供了onsaveinstancestate方法,這個方法接收一個bundle類型參數,我們可以将狀态和資料儲存到bundle對象中,這樣的話,就算activity被系統銷毀,隻要使用者重新啟動activity調用oncreate方法,我們就能在oncreate方法中得到bundle對象,并根據這個對象中的資料将activity恢複到之前的樣子。
具體可以看以下代碼。
我們在onsaveinstancestate方法中将eoe這個值以鍵為prestate存入了outstate這個bundle對象,之後我們就能在oncreate方法中,通過savedinstancestate這個bundle對象取得eoe這個值了。
注意
onsaveinstancestate方法并不一定會被調用,因為有些場景是不需要儲存狀态資料的,比如,當使用者單擊“後退”按鈕的時候,因為使用者已經明确要關閉目前activity了。
其實,即使不覆寫onsaveinstancestate方法,該方法依然會預設儲存activity的某些狀态資料,比如activity裡各個ui控件的狀态。android裡幾乎所有的ui控件都适當地實作了onsaveinstancestate方法,是以,當activity被摧毀并重新恢複時,這些控件會自動儲存和恢複狀态。比如edittext控件會自動儲存和恢複輸入的資料,checkbox也會儲存它是否已經選中的狀态,當然,要做到這點你也需要給這些控件指定id,不然這個控件是不會自動進行資料和狀态的儲存與恢複的。
由于onsaveinstancestate方法不一定會被調用,是以,我們不适合在這個方法中儲存持久化資料,例如向資料庫中插入記錄等,類似這種操作,應該放到onpause方法中進行(前面提過)。onsaveinstancestate方法其實隻适合儲存瞬時狀态資料,比如某些成員變量等。
小知識
除了系統因為記憶體不足,會摧毀你處于暫停或停止狀态的activity之外,系統設定的改變也會導緻activity的摧毀和重建。這個我們在本章上面節點“配置改變”中提到過,是以,如果你想要測試你的程式恢複狀态的能力,簡單的旋轉裝置,讓螢幕橫豎屏切換是非常好的方式。