http://ice-k.iteye.com/blog/1018956
Activity的生命周期里并沒有提到onSaveInstanceState的觸發(fā),這個函數(shù)提供了為我們在某些情況下保存Activity信息的機會,但需要注意的是這個函數(shù)不是什么時候都會被調(diào)用的,官方文檔解釋的比較清楚,特此
翻譯一下。
原文出處: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被殺掉之前調(diào)用保存每個實例的狀態(tài),以保證該狀態(tài)可以在onCreate(Bundle)或者
onRestoreInstanceState(Bundle)
(傳入的Bundle參數(shù)是由onSaveInstanceState封裝好的)中恢復(fù)。這個方法在一個activity被殺死前調(diào)用,當該
activity在將來某個時刻回來時可以恢復(fù)其先前狀態(tài)。例如,如果activity B啟用后位于activity
A的前端,在某個時刻activity
A因為系統(tǒng)回收資源的問題要被殺掉,A通過onSaveInstanceState將有機會保存其用戶界面狀態(tài),使得將來用戶返回到activity
A時能通過onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢復(fù)界面的狀態(tài)。
??? 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生命周期回調(diào)如onPause()或onStop()搞混淆了,onPause()在activtiy被放置到背景或者
自行銷毀時總會被調(diào)用,onStop()在activity被銷毀時被調(diào)用。一個會調(diào)用onPause()和onStop(),但不觸發(fā)
onSaveInstanceState的例子是當用戶從activity B返回到activity
A時:沒有必要調(diào)用B的onSaveInstanceState(Bundle),此時的B實例永遠不會被恢復(fù),因此系統(tǒng)會避免調(diào)用它。一個調(diào)用
onPause()但不調(diào)用onSaveInstanceState的例子是當activity B啟動并處在activity
A的前端:如果在B的整個生命周期里A的用戶界面狀態(tài)都沒有被破壞的話,系統(tǒng)是不會調(diào)用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().
?????
默認的實現(xiàn)負責(zé)了大部分UI實例狀態(tài)(的保存),采用的方式是調(diào)用UI層上每個擁有id的view的onSaveInstanceState()
,并且保存當前獲得焦點的view的id(所有保存的狀態(tài)信息都會在默認的onRestoreInstanceState(Bundle)實現(xiàn)中恢復(fù))。
如果你覆寫這個方法來保存額外的沒有被各個view保存的信息,你可能想要在默認實現(xiàn)過程中調(diào)用或者自己保存每個視圖的所有狀態(tài)。如果被調(diào)用,這個方法會
在onStop()前被觸發(fā),但系統(tǒng)并不保證是否在onPause()之前或者之后觸發(fā)。
很多不明白Activity類中包含的onSaveInstanceState和onRestoreInstanceState有什么用,首先聲
明下使用這兩個方法時一定要注意情況和了解Activity的生命周期,否則有的時候?
onSaveInstanceState和onRestoreInstanceState
可能不會被觸發(fā),雖然他們都是Activity的重寫方法。(文/Android開發(fā)網(wǎng))
他們比較常用到的地方是
Sensor、Land和Port布局的自動切換,過去Android開發(fā)網(wǎng)曾經(jīng)說過解決橫屏和豎屏切換帶來的數(shù)據(jù)被置空或者說onCreate被重復(fù)調(diào)
用問題,其實Android提供的onSaveInstanceState方法可以保存當前的窗口狀態(tài)在即將布局切換前或當前Activity被推入歷史
棧,其實布局切換也調(diào)用過onPause所以被推入Activity的history
stack,如果我們的Activity在后臺沒有因為運行內(nèi)存吃緊被清理,則切換回時會觸發(fā)onRestoreInstanceState方法。
這兩個方法中參數(shù)均為Bundle,可以存放類似 SharedPreferences 的數(shù)據(jù),所以使用它們作為當前窗口的狀態(tài)保存是比較合適的。實際使用代碼
@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觸發(fā)的時機
已有 199 次閱讀 2011-3-10 10:32 |個人分類:Android|關(guān)鍵詞: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變得“容易”被系統(tǒng)銷毀時,該activity的onSaveInstanceState就會被執(zhí)行,除非該activity是被用戶主動銷毀的,例如當用戶按BACK鍵的時候。
注意上面的雙引號,何為“容易”?言下之意就是該activity還沒有被銷毀,而僅僅是一種可能性。這種可能性有哪些?通過重寫一個
activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我
們可以清楚地知道當某個activity(假定為activity
A)顯示在當前task的最上層時,其onSaveInstanceState方法會在什么時候被執(zhí)行,有這么幾種情況:
1、當用戶按下HOME鍵時。這是顯而易見的,系統(tǒng)不知道你按下HOME后要運行多少其他的程序,自然也不知道activity A是否會被銷毀,故系統(tǒng)會調(diào)用onSaveInstanceState,讓用戶有機會保存某些非永久性的數(shù)據(jù)。以下幾種情況的分析都遵循該原則
2、長按HOME鍵,選擇運行其他的程序時。
3、按下電源按鍵(關(guān)閉屏幕顯示)時。
4、從activity A中啟動一個新的activity時。
5、屏幕方向切換時,例如從豎屏切換到橫屏?xí)r。在屏幕切換之前,系統(tǒng)會銷毀activity A,在屏幕切換之后系統(tǒng)又會自動地創(chuàng)建activity A,所以onSaveInstanceState一定會被執(zhí)行
總而言之,onSaveInstanceState的調(diào)用遵循一個重要原則,即當系統(tǒng)“未經(jīng)你許可”時銷毀了你的activity,則
onSaveInstanceState會被系統(tǒng)調(diào)用,這是系統(tǒng)的責(zé)任,因為它必須要提供一個機會讓你保存你的數(shù)據(jù)(當然你不保存那就隨便你了)。
至于onRestoreInstanceState方法,需要注意的是,onSaveInstanceState方法和
onRestoreInstanceState方法“不一定”是成對的被調(diào)用的,onRestoreInstanceState被調(diào)用的前提
是,activity A“確實”被系統(tǒng)銷毀了,而如果僅僅是停留在有這種可能性的情況下,則該方法不會被調(diào)用,例如,當正在顯示activity
A的時候,用戶按下HOME鍵回到主界面,然后用戶緊接著又返回到activity A,這種情況下activity
A一般不會因為內(nèi)存的原因被系統(tǒng)銷毀,故activity A的onRestoreInstanceState方法不會被執(zhí)行
另外,onRestoreInstanceState的bundle參數(shù)也會傳遞到onCreate方法中,你也可以選擇在onCreate方法中做數(shù)據(jù)還原