http://ice-k.iteye.com/blog/1018956
Activity的生命周期里并沒有提到onSaveInstanceState的觸發,這個函數提供了為我們在某些情況下保存Activity信息的機會,但需要注意的是這個函數不是什么時候都會被調用的,官方文檔解釋的比較清楚,特此
翻譯一下。
原文出處:android-sdk-windows-1.5_r3/docs/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)
protected void onSaveInstanceState (Bundle outState)
?????? Called to retrieve per-instance state from an activity before
being killed so that the state can be restored in onCreate(Bundle) or
onRestoreInstanceState(Bundle) (the Bundle populated by this method will
be passed to both). This method is called before an activity may be
killed so that when it comes back some time in the future it can restore
its state. For example, if activity B is launched in front of activity
A, and at some point activity A is killed to reclaim resources, activity
A will have a chance to save the current state of its user interface
via this method so that when the user returns to activity A, the state
of the user interface can be restored via onCreate(Bundle) or
onRestoreInstanceState(Bundle).
???
在activity被殺掉之前調用保存每個實例的狀態,以保證該狀態可以在onCreate(Bundle)或者
onRestoreInstanceState(Bundle)
(傳入的Bundle參數是由onSaveInstanceState封裝好的)中恢復。這個方法在一個activity被殺死前調用,當該
activity在將來某個時刻回來時可以恢復其先前狀態。例如,如果activity B啟用后位于activity
A的前端,在某個時刻activity
A因為系統回收資源的問題要被殺掉,A通過onSaveInstanceState將有機會保存其用戶界面狀態,使得將來用戶返回到activity
A時能通過onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢復界面的狀態。
??? Do not confuse this method with activity lifecycle callbacks
such as onPause(), which is always called when an activity is being
placed in the background or on its way to destruction, or onStop() which
is called before destruction. One example of when onPause() and
onStop() is called and not this method is when a user navigates back
from activity B to activity A: there is no need to call
onSaveInstanceState(Bundle) on B because that particular instance will
never be restored, so the system avoids calling it. An example when
onPause() is called and not onSaveInstanceState(Bundle) is when activity
B is launched in front of activity A: the system may avoid calling
onSaveInstanceState(Bundle) on activity A if it isn't killed during the
lifetime of B since the state of the user interface of A will stay
intact.
??
???
不要將這個方法和activity生命周期回調如onPause()或onStop()搞混淆了,onPause()在activtiy被放置到背景或者
自行銷毀時總會被調用,onStop()在activity被銷毀時被調用。一個會調用onPause()和onStop(),但不觸發
onSaveInstanceState的例子是當用戶從activity B返回到activity
A時:沒有必要調用B的onSaveInstanceState(Bundle),此時的B實例永遠不會被恢復,因此系統會避免調用它。一個調用
onPause()但不調用onSaveInstanceState的例子是當activity B啟動并處在activity
A的前端:如果在B的整個生命周期里A的用戶界面狀態都沒有被破壞的話,系統是不會調用activity
A的onSaveInstanceState(Bundle)的。
??? The default implementation takes care of most of the UI
per-instance state for you by calling onSaveInstanceState() on each view
in the hierarchy that has an id, and by saving the id of the currently
focused view (all of which is restored by the default implementation of
onRestoreInstanceState(Bundle)). If you override this method to save
additional information not captured by each individual view, you will
likely want to call through to the default implementation, otherwise be
prepared to save all of the state of each view yourself. If called, this
method will occur before onStop(). There are no guarantees about
whether it will occur before or after onPause().
?????
默認的實現負責了大部分UI實例狀態(的保存),采用的方式是調用UI層上每個擁有id的view的onSaveInstanceState()
,并且保存當前獲得焦點的view的id(所有保存的狀態信息都會在默認的onRestoreInstanceState(Bundle)實現中恢復)。
如果你覆寫這個方法來保存額外的沒有被各個view保存的信息,你可能想要在默認實現過程中調用或者自己保存每個視圖的所有狀態。如果被調用,這個方法會
在onStop()前被觸發,但系統并不保證是否在onPause()之前或者之后觸發。
很多不明白Activity類中包含的onSaveInstanceState和onRestoreInstanceState有什么用,首先聲
明下使用這兩個方法時一定要注意情況和了解Activity的生命周期,否則有的時候?
onSaveInstanceState和onRestoreInstanceState
可能不會被觸發,雖然他們都是Activity的重寫方法。(文/Android開發網)
他們比較常用到的地方是
Sensor、Land和Port布局的自動切換,過去Android開發網曾經說過解決橫屏和豎屏切換帶來的數據被置空或者說onCreate被重復調
用問題,其實Android提供的onSaveInstanceState方法可以保存當前的窗口狀態在即將布局切換前或當前Activity被推入歷史
棧,其實布局切換也調用過onPause所以被推入Activity的history
stack,如果我們的Activity在后臺沒有因為運行內存吃緊被清理,則切換回時會觸發onRestoreInstanceState方法。
這兩個方法中參數均為Bundle,可以存放類似 SharedPreferences 的數據,所以使用它們作為當前窗口的狀態保存是比較合適的。實際使用代碼
@Override
? protected void onSaveInstanceState(Bundle outState){
??????????? outState.putString("lastPath", "/sdcard/android123/cwj/test");
? }
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String cwjString = savedInstanceState.getString("lastPath");
}
onSaveInstanceState和onRestoreInstanceState觸發的時機
已有 199 次閱讀 2011-3-10 10:32 |個人分類:Android|關鍵詞:onSaveInstanceState onRestoreInstanceState
先看Application Fundamentals上的一段話:
Android calls onSaveInstanceState() before the activity becomes
vulnerable to being destroyed by the system, but does not bother calling
it when the instance is actually being destroyed by a user action (such
as pressing the BACK key)
從這句話可以知道,當某個activity變得“容易”被系統銷毀時,該activity的onSaveInstanceState就會被執行,除非該activity是被用戶主動銷毀的,例如當用戶按BACK鍵的時候。
注意上面的雙引號,何為“容易”?言下之意就是該activity還沒有被銷毀,而僅僅是一種可能性。這種可能性有哪些?通過重寫一個
activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我
們可以清楚地知道當某個activity(假定為activity
A)顯示在當前task的最上層時,其onSaveInstanceState方法會在什么時候被執行,有這么幾種情況:
1、當用戶按下HOME鍵時。這是顯而易見的,系統不知道你按下HOME后要運行多少其他的程序,自然也不知道activity A是否會被銷毀,故系統會調用onSaveInstanceState,讓用戶有機會保存某些非永久性的數據。以下幾種情況的分析都遵循該原則
2、長按HOME鍵,選擇運行其他的程序時。
3、按下電源按鍵(關閉屏幕顯示)時。
4、從activity A中啟動一個新的activity時。
5、屏幕方向切換時,例如從豎屏切換到橫屏時。在屏幕切換之前,系統會銷毀activity A,在屏幕切換之后系統又會自動地創建activity A,所以onSaveInstanceState一定會被執行
總而言之,onSaveInstanceState的調用遵循一個重要原則,即當系統“未經你許可”時銷毀了你的activity,則
onSaveInstanceState會被系統調用,這是系統的責任,因為它必須要提供一個機會讓你保存你的數據(當然你不保存那就隨便你了)。
至于onRestoreInstanceState方法,需要注意的是,onSaveInstanceState方法和
onRestoreInstanceState方法“不一定”是成對的被調用的,onRestoreInstanceState被調用的前提
是,activity A“確實”被系統銷毀了,而如果僅僅是停留在有這種可能性的情況下,則該方法不會被調用,例如,當正在顯示activity
A的時候,用戶按下HOME鍵回到主界面,然后用戶緊接著又返回到activity A,這種情況下activity
A一般不會因為內存的原因被系統銷毀,故activity A的onRestoreInstanceState方法不會被執行
另外,onRestoreInstanceState的bundle參數也會傳遞到onCreate方法中,你也可以選擇在onCreate方法中做數據還原