Save & Restore State與之前的例子Android ApiDemo樣本解析(9):App->Activity->Persistent State 實現的UI類似,但功能和實現方法稍有不同。(9)是通過Shared Preferences 和 Activity 的onPause() ,和onResume()來保持UI中 EditText 的值。本例是通過onSaveInstanceState(Bundle savedBundle) 來實現保持UI狀態。 和onPause,onResume不同的是,onSaveInstanceState不是Activity Life cycle的一部分,也不一定會在Activity 被destroyed前執行,比如說使用者按“Back”按鍵回退到前一個Activity時,當前的Activity並不會調用onSaveInstanceState方法,因為這時是使用者指明想關閉當前Activity,而onPause一定會執行,因為onPause 是Activity生命週期的一個狀態。如果onSaveInstanceState被調用的話,它一定會在onStop之前調用,有時會在onPause之前調用。
onSaveInstanceState設計在當Activity destroy之前調用(如當Android切換到其它應用,此時Android根據系統資源的分配情況,用可能會將在後台啟動並執行Activity清除,或是系統配置改變,比如螢幕從縱向放平,當前的Activity會先被Destory,然後根據當前配置重新建立當前Activity的執行個體。此時Activity的onSaveInstanceState會在Activity Destroy之前調用,此時應在onSaveInstanceState將一些UI狀態臨時儲存中Bundle中。然後Android系統會重新執行Activity的onCreate方法,傳入參數為Bundle對象。如果在onSaveInstanceState設定了,這個Bundle對象即是之前儲存的Bundle對象,應用可以在onCreate 或是onRestoreInstanceState(Bundle savedInstanceState) 恢複UI狀態,這樣可以做到在應用或是Activity重啟時能保持上此退出時的狀態。
但是看看SaveRestoreState.java中似乎沒有任何與Save /Restore State 相關的代碼,方法getSavedText和setSavedText和本例無關。
這是因為Activity的預設onSaveInstanceState實現完成了對UI狀態的Save和Restore。例子中上面的EditText輸入在Activity重啟時會恢複,而下面的EditText輸入不會被儲存和恢複。Activity的預設onSaveInstanceState實現只會對定義了ID(android:id)的View實現Save 和Restore.來看看R.layout.save_restore_state中的定義:
<EditText android:id=”@+id/saved”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_weight=”1″
android:background=”@drawable/green”
android:text=”@string/initial_text”
android:freezesText=”true”>
<requestFocus />
< /EditText>
….
<EditText
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_weight=”1″
android:background=”@drawable/red”
android:text=”@string/initial_text”>
< /EditText>
上面的EditText定義了ID而下面的EditText沒有定義ID。這可以通過旋轉螢幕來測試。旋轉螢幕可以保證當前activity先被Destory然後再Create:在上下EditText輸入值,然後旋轉螢幕,可以看到只有上面的EditText值被保留。
註:在Emulator上,可以先按下“NumLock”,然後按7,9來旋轉螢幕。
還是有些情況下需要重載onRestoreInstanceState,此時別忘了調用super.onRestoreInstanceState
作者:mapdigit