android onSaveInstanceState方法

1. onSaveInstanceState和onRestoreInstanceState基本作用

onSaveInstanceState是用來保存UI狀態(tài)的劈猿,你可以使用它保存你所想保存的東西,在Activity殺死之前庐镐,它一般在onStop或者onPause之前觸發(fā)变逃,onRestoreInstanceState則是在onResume之前觸發(fā)回復(fù)狀態(tài),至于復(fù)寫這個方法后onCreate方法是否會被調(diào)用名眉。

1.Activity被殺死了凰棉,onCreate會被調(diào)用,且onRestoreInstanceState 在 onResume之前恢復(fù)上次保存的信息福压。

2.Activity沒被殺死或舞,onCreate不會被調(diào)用映凳,但onRestoreInstanceState 仍然會被調(diào)用,在 onResume之前恢復(fù)上次保存的信息诈豌。

onSaveInstanceState和onRestoreInstanceState 是一對兄弟矫渔,一個負(fù)責(zé)存儲,一個負(fù)責(zé)取出.“不一定”是成對的被調(diào)用的顿痪。

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它們不同于 onCreate()、onPause()等生命周期方法叠聋,它們并不一定會被觸發(fā)。當(dāng)應(yīng)用遇到意外情況(如:內(nèi)存不足虏束、用戶直接按Home鍵)由系統(tǒng)銷毀一個Activity時镇匀,onSaveInstanceState() 會被調(diào)用袜啃。但是當(dāng)用戶主動去銷毀一個Activity時,例如在應(yīng)用中按返回鍵晰韵,onSaveInstanceState()就不會被調(diào)用熟妓。因為在這種情況下,用戶的行為決定了不需要保存Activity的狀態(tài)只恨。通常onSaveInstanceState()只適合用于保存一些臨時性的狀態(tài)抬虽,而onPause()適合用于數(shù)據(jù)的持久化保存。

在activity被殺掉之前調(diào)用保存每個實例的狀態(tài),以保證該狀態(tài)可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) (傳入的Bundle參數(shù)是由onSaveInstanceState封裝好的)中恢復(fù)缰猴。這個方法在一個activity被殺死前調(diào)用疤剑,當(dāng)該activity在將來某個時刻回來時可以恢復(fù)其先前狀態(tài)隘膘。

例如,如果activity B啟用后位于activity A的前端弯菊,在某個時刻activity A因為系統(tǒng)回收資源的問題要被殺掉,A通過onSaveInstanceState將有機(jī)會保存其用戶界面狀態(tài)钦铁,使得將來用戶返回到activity A時能通過onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢復(fù)界面的狀態(tài)牛曹。

關(guān)于onSaveInstanceState (),是在函數(shù)里面保存一些View有用的數(shù)據(jù)到一個Parcelable對象并返回超营。在Activity的onSaveInstanceState(Bundle outState)中調(diào)用View的onSaveInstanceState ()阅虫,返回Parcelable對象,

接著用Bundle的putParcelable方法保存在BundlesavedInstanceState中米碰。

當(dāng)系統(tǒng)調(diào)用Activity的的onRestoreInstanceState(Bundle savedInstanceState)時购城,同過Bundle的getParcelable方法得到Parcelable對象工猜,然后把該Parcelable對象傳給View的onRestoreInstanceState (Parcelable state)。在的View的onRestoreInstanceState中從Parcelable讀取保存的數(shù)據(jù)以便View使用史侣。

這就是onSaveInstanceState() 和onRestoreInstanceState() 兩個函數(shù)的基本作用和用法魏身。

2. onSaveInstanceState() 什么時候調(diào)用

先看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)

從這句話可以知道箭昵,當(dāng)某個activity變得“容易”被系統(tǒng)銷毀時,該activity的onSaveInstanceState就會被執(zhí)行正林,除非該activity是被用戶主動銷毀的颤殴,例如當(dāng)用戶按BACK鍵的時候。

注意上面的雙引號杈绸,何為“容易”?言下之意就是該activity還沒有被銷毀塑娇,而僅僅是一種可能性劫侧。這種可能性有哪些?通過重寫一個activity的所有生命周期的onXXX方法奇瘦,包括onSaveInstanceState和onRestoreInstanceState方法劲弦,我們可以清楚地知道當(dāng)某個activity(假定為activity A)顯示在當(dāng)前task的最上層時邑跪,其onSaveInstanceState方法會在什么時候被執(zhí)行呼猪,有這么幾種情況:

1、當(dāng)用戶按下HOME鍵時

這是顯而易見的轴踱,系統(tǒng)不知道你按下HOME后要運行多少其他的程序谚赎,自然也不知道activity A是否會被銷毀壶唤,故系統(tǒng)會調(diào)用onSaveInstanceState,讓用戶有機(jī)會保存某些非永久性的數(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)用遵循一個重要原則昵宇,即當(dāng)系統(tǒng)“未經(jīng)你許可”時銷毀了你的activity,則onSaveInstanceState會被系統(tǒng)調(diào)用儿子,這是系統(tǒng)的責(zé)任瓦哎,因為它必須要提供一個機(jī)會讓你保存你的數(shù)據(jù)(當(dāng)然你不保存那就隨便你了)。

3. onRestoreInstanceState()什么時候調(diào)用

至于onRestoreInstanceState方法柔逼,需要注意的是蒋譬,onSaveInstanceState方法和onRestoreInstanceState方法“不一定”是成對的被調(diào)用的。

onRestoreInstanceState被調(diào)用的前提是卒落,activity A“確實”被系統(tǒng)銷毀了羡铲,而如果僅僅是停留在有這種可能性的情況下,則該方法不會被調(diào)用儡毕,例如,當(dāng)正在顯示activity A的時候腰湾,用戶按下HOME鍵回到主界面雷恃,然后用戶緊接著又返回到activity A,這種情況下activity A一般不會因為內(nèi)存的原因被系統(tǒng)銷毀费坊,故activity A的onRestoreInstanceState方法不會被執(zhí)行.此處也說明以上二者倒槐,大多數(shù)情況下不成對被使用。

另外附井,onRestoreInstanceState的bundle參數(shù)也會傳遞到onCreate方法中讨越,你也可以選擇在onCreate方法中做數(shù)據(jù)還原.

onRestoreInstanceState()在onStart() 和 onPostCreate(Bundle)之間調(diào)用两残。

4. onSaveInstanceState()方法的默認(rèn)實現(xiàn)

如果我們沒有覆寫onSaveInstanceState()方法, 此方法的默認(rèn)實現(xiàn)會自動保存activity中的某些狀態(tài)數(shù)據(jù), 比如activity中各種UI控件的狀態(tài).。android應(yīng)用框架中定義的幾乎所有UI控件都恰當(dāng)?shù)膶崿F(xiàn)了onSaveInstanceState()方法,因此當(dāng)activity被摧毀和重建時, 這些UI控件會自動保存和恢復(fù)狀態(tài)數(shù)據(jù). 比如EditText控件會自動保存和恢復(fù)輸入的數(shù)據(jù),而CheckBox控件會自動保存和恢復(fù)選中狀態(tài).開發(fā)者只需要為這些控件指定一個唯一的ID(通過設(shè)置android:id屬性即可), 剩余的事情就可以自動完成了.如果沒有為控件指定ID, 則這個控件就不會進(jìn)行自動的數(shù)據(jù)保存和恢復(fù)操作把跨。

由上所述, 如果我們需要覆寫onSaveInstanceState()方法, 一般會在第一行代碼中調(diào)用該方法的默認(rèn)實現(xiàn):super.onSaveInstanceState(outState)人弓。

5. 是否需要重寫onSaveInstanceState()方法

既然該方法的默認(rèn)實現(xiàn)可以自動的保存UI控件的狀態(tài)數(shù)據(jù), 那什么時候需要覆寫該方法呢?

如果需要保存額外的數(shù)據(jù)時, 就需要覆寫onSaveInstanceState()方法。大家需要注意的是:onSaveInstanceState()方法只適合保存瞬態(tài)數(shù)據(jù), 比如UI控件的狀態(tài), 成員變量的值等着逐,而不應(yīng)該用來保存持久化數(shù)據(jù)崔赌,持久化數(shù)據(jù)應(yīng)該當(dāng)用戶離開當(dāng)前的activity時,在onPause()中保存(比如將數(shù)據(jù)保存到數(shù)據(jù)庫或文件中)耸别。說到這里健芭,還要說一點的就是在onPause()中不適合用來保存比較費時的數(shù)據(jù),所以這點要理解秀姐。

由于onSaveInstanceState()方法方法不一定會被調(diào)用, 因此不適合在該方法中保存持久化數(shù)據(jù), 例如向數(shù)據(jù)庫中插入記錄等. 保存持久化數(shù)據(jù)的操作應(yīng)該放在onPause()中慈迈。若是永久性值,則在onPause()中保存囊扳;若大量吩翻,則另開線程吧兜看,別阻塞UI線程锥咸。

6. 引發(fā)activity銷毀和重建的其它情況

除了系統(tǒng)處于內(nèi)存不足的原因會摧毀activity之外, 某些系統(tǒng)設(shè)置的改變也會導(dǎo)致activity的摧毀和重建. 例如改變屏幕方向(見上例), 改變設(shè)備語言設(shè)定, 鍵盤彈出等。

另外细移,當(dāng)屏幕的方向發(fā)生了改變搏予, Activity會被摧毀并且被重新創(chuàng)建,如果你想在Activity被摧毀前緩存一些數(shù)據(jù)弧轧,并且在Activity被重新創(chuàng)建后恢復(fù)緩存的數(shù)據(jù)雪侥。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市精绎,隨后出現(xiàn)的幾起案子速缨,更是在濱河造成了極大的恐慌,老刑警劉巖代乃,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旬牲,死亡現(xiàn)場離奇詭異,居然都是意外死亡搁吓,警方通過查閱死者的電腦和手機(jī)原茅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堕仔,“玉大人擂橘,你說我怎么就攤上這事∧牵” “怎么了通贞?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵朗若,是天一觀的道長。 經(jīng)常有香客問我昌罩,道長捡偏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任峡迷,我火速辦了婚禮银伟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绘搞。我一直安慰自己彤避,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布夯辖。 她就那樣靜靜地躺著琉预,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蒿褂。 梳的紋絲不亂的頭發(fā)上圆米,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音啄栓,去河邊找鬼娄帖。 笑死,一個胖子當(dāng)著我的面吹牛昙楚,可吹牛的內(nèi)容都是我干的近速。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼堪旧,長吁一口氣:“原來是場噩夢啊……” “哼削葱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起淳梦,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤析砸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后爆袍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體首繁,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年螃宙,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛮瞄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡谆扎,死狀恐怖挂捅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情堂湖,我是刑警寧澤闲先,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布状土,位于F島的核電站,受9級特大地震影響伺糠,放射性物質(zhì)發(fā)生泄漏蒙谓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一训桶、第九天 我趴在偏房一處隱蔽的房頂上張望累驮。 院中可真熱鬧,春花似錦舵揭、人聲如沸谤专。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽置侍。三九已至,卻和暖如春拦焚,著一層夾襖步出監(jiān)牢的瞬間蜡坊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工赎败, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留秕衙,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓螟够,卻偏偏與公主長得像灾梦,于是被迫代替她去往敵國和親峡钓。 傳聞我的和親對象是個殘疾皇子妓笙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容