Android開發(fā)之InstanceState詳解

本文介紹Android中關(guān)于Activity的兩個(gè)神秘方法:onSaveInstanceState() 和 onRestoreInstanceState()拯田,并且在介紹這兩個(gè)方法之后典格,再分別來實(shí)現(xiàn)使用InstanceState保存和恢復(fù)數(shù)據(jù)功能、Android實(shí)現(xiàn)屏幕旋轉(zhuǎn)異步下載效果這樣兩個(gè)示例释牺。

首先來介紹onSaveInstanceState() 和 onRestoreInstanceState()?。關(guān)于這兩個(gè)方法复亏,一些朋友可能在Android開發(fā)過程中很少用到做入,但在有時(shí)候掌握其用法會(huì)幫我們起到比較好的效果。尤其是在應(yīng)用程序在不知道的情況下退出后蛉加,如何實(shí)現(xiàn)其數(shù)據(jù)保存的功能蚜枢。先來讓我們看下這兩個(gè)方法的有什么樣的作用。

1.?基本作用:

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法针饥,它們不同于 onCreate()厂抽、onPause()等生命周期方法,它們并不一定會(huì)被觸發(fā)丁眼。當(dāng)應(yīng)用遇到意外情況(如:內(nèi)存不足筷凤、用戶直接按Home鍵)由系統(tǒng)銷毀一個(gè)Activity時(shí),onSaveInstanceState() 會(huì)被調(diào)用苞七。但是當(dāng)用戶主動(dòng)去銷毀一個(gè)Activity時(shí)藐守,例如在應(yīng)用中按返回鍵,onSaveInstanceState()就不會(huì)被調(diào)用莽鸭。因?yàn)樵谶@種情況下吗伤,用戶的行為決定了不需要保存Activity的狀態(tài)吃靠。通常onSaveInstanceState()只適合用于保存一些臨時(shí)性的狀態(tài)硫眨,而onPause()適合用于數(shù)據(jù)的持久化保存。

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

例如族奢,如果activity B啟用后位于activity A的前端姥闭,在某個(gè)時(shí)刻activity A因?yàn)橄到y(tǒng)回收資源的問題要被殺掉,A通過onSaveInstanceState將有機(jī)會(huì)保存其用戶界面狀態(tài)越走,使得將來用戶返回到activity A時(shí)能通過onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢復(fù)界面的狀態(tài)棚品。

關(guān)于onSaveInstanceState ()靠欢,是在函數(shù)里面保存一些View有用的數(shù)據(jù)到一個(gè)Parcelable對(duì)象并返回。在Activity的onSaveInstanceState(Bundle outState)中調(diào)用View的onSaveInstanceState ()铜跑,返回Parcelable對(duì)象门怪,

接著用Bundle的putParcelable方法保存在Bundle ?savedInstanceState中。

當(dāng)系統(tǒng)調(diào)用Activity的的onRestoreInstanceState(Bundle savedInstanceState)時(shí)锅纺,?同過Bundle的getParcelable方法得到Parcelable對(duì)象掷空,然后把該P(yáng)arcelable對(duì)象傳給View的onRestoreInstanceState (Parcelable state)。在的View的onRestoreInstanceState中從Parcelable讀取保存的數(shù)據(jù)以便View使用囤锉。

這就是onSaveInstanceState() 和?onRestoreInstanceState() 兩個(gè)函數(shù)的基本作用和用法坦弟。

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

先看Application Fundamentals上的一段話:

Android calls onSaveInstanceState() before the activitybecomes vulnerable to being destroyed by the system, but does not bothercalling it when the instance is actually being destroyed by a user action (suchas pressing the BACK key).

從這句話可以知道,當(dāng)某個(gè)activity變得"容易"被系統(tǒng)銷毀時(shí)官地,該activity的onSaveInstanceState()就會(huì)被執(zhí)行酿傍,除非該activity是被用戶主動(dòng)銷毀的,例如當(dāng)用戶按BACK鍵的時(shí)候驱入。

注意上面的雙引號(hào)拧粪,何為"容易"?意思就是說該activity還沒有被銷毀沧侥,而僅僅是一種可能性可霎。這種可能性有哪些?通過重寫一個(gè)activity的所有生命周期的onXXX方法宴杀,包括onSaveInstanceState()和onRestoreInstanceState()?方法癣朗,我們可以清楚地知道當(dāng)某個(gè)activity(假定為activity A)顯示在當(dāng)前task的最上層時(shí),其onSaveInstanceState()方法會(huì)在什么時(shí)候被執(zhí)行旺罢,有這么幾種情況:

(1)旷余、當(dāng)用戶按下HOME鍵時(shí)。

這是顯而易見的扁达,系統(tǒng)不知道你按下HOME后要運(yùn)行多少其他的程序正卧,自然也不知道activity A是否會(huì)被銷毀,因此系統(tǒng)會(huì)調(diào)用onSaveInstanceState()跪解,讓用戶有機(jī)會(huì)保存某些非永久性的數(shù)據(jù)炉旷。以下幾種情況的分析都遵循該原則

(2)、長按HOME鍵叉讥,選擇運(yùn)行其他的程序時(shí)窘行。

(3)、按下電源按鍵(關(guān)閉屏幕顯示)時(shí)图仓。

(4)罐盔、從activity A中啟動(dòng)一個(gè)新的activity時(shí)。

(5)救崔、屏幕方向切換時(shí)惶看,例如從豎屏切換到橫屏?xí)r捏顺。

在屏幕切換之前,系統(tǒng)會(huì)銷毀activity A纬黎,在屏幕切換之后系統(tǒng)又會(huì)自動(dòng)地創(chuàng)建activity A草丧,所以onSaveInstanceState()一定會(huì)被執(zhí)行,且也一定會(huì)執(zhí)行onRestoreInstanceState()莹桅。

總而言之昌执,onSaveInstanceState()的調(diào)用遵循一個(gè)重要原則,即當(dāng)系統(tǒng)存在“未經(jīng)你許可”時(shí)銷毀了我們的activity的可能時(shí)诈泼,則onSaveInstanceState()會(huì)被系統(tǒng)調(diào)用懂拾,這是系統(tǒng)的責(zé)任,因?yàn)樗仨氁峁┮粋€(gè)機(jī)會(huì)讓你保存你的數(shù)據(jù)(當(dāng)然你不保存那就隨便你了)铐达。如果調(diào)用岖赋,調(diào)用將發(fā)生在onPause()或onStop()方法之前。(雖然測試時(shí)發(fā)現(xiàn)多數(shù)在onPause()前)

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

onRestoreInstanceState()被調(diào)用的前提是瓮孙,activity A“確實(shí)”被系統(tǒng)銷毀了唐断,而如果僅僅是停留在有這種可能性的情況下,則該方法不會(huì)被調(diào)用杭抠,例如脸甘,當(dāng)正在顯示activity A的時(shí)候,用戶按下HOME鍵回到主界面偏灿,然后用戶緊接著又返回到activity A丹诀,這種情況下activity A一般不會(huì)因?yàn)閮?nèi)存的原因被系統(tǒng)銷毀,故activity A的onRestoreInstanceState方法不會(huì)被執(zhí)行 此也說明上二者翁垂,大多數(shù)情況下不成對(duì)被使用铆遭。

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

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

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

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

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

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

如果需要保存額外的數(shù)據(jù)時(shí), 就需要覆寫onSaveInstanceState()方法啼肩。大家需要注意的是:onSaveInstanceState()方法只適合保存瞬態(tài)數(shù)據(jù), 比如UI控件的狀態(tài), 成員變量的值等橄妆,而不應(yīng)該用來保存持久化數(shù)據(jù),持久化數(shù)據(jù)應(yīng)該當(dāng)用戶離開當(dāng)前的 activity時(shí)疟游,在 onPause() 中保存(比如將數(shù)據(jù)保存到數(shù)據(jù)庫或文件中)呼畸。說到這里痕支,還要說一點(diǎn)的就是在onPause()中不適合用來保存比較費(fèi)時(shí)的數(shù)據(jù)颁虐,所以這點(diǎn)要理解。

由于onSaveInstanceState()方法方法不一定會(huì)被調(diào)用, 因此不適合在該方法中保存持久化數(shù)據(jù), 例如向數(shù)據(jù)庫中插入記錄等. 保存持久化數(shù)據(jù)的操作應(yīng)該放在onPause()中卧须。若是永久性值另绩,則在onPause()中保存儒陨;若大量,則另開線程吧笋籽,別阻塞UI線程蹦漠。

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

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

另外车海,當(dāng)屏幕的方向發(fā)生了改變笛园, Activity會(huì)被摧毀并且被重新創(chuàng)建,如果你想在Activity被摧毀前緩存一些數(shù)據(jù)侍芝,并且在Activity被重新創(chuàng)建后恢復(fù)緩存的數(shù)據(jù)研铆。可以重寫Activity的 onSaveInstanceState() 和 onRestoreInstanceState()方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末州叠,一起剝皮案震驚了整個(gè)濱河市棵红,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咧栗,老刑警劉巖逆甜,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異致板,居然都是意外死亡交煞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門斟或,熙熙樓的掌柜王于貴愁眉苦臉地迎上來错敢,“玉大人,你說我怎么就攤上這事缕粹≈擅” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵平斩,是天一觀的道長亚享。 經(jīng)常有香客問我,道長绘面,這世上最難降的妖魔是什么欺税? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮揭璃,結(jié)果婚禮上晚凿,老公的妹妹穿的比我還像新娘。我一直安慰自己瘦馍,他們只是感情好歼秽,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著情组,像睡著了一般燥筷。 火紅的嫁衣襯著肌膚如雪箩祥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天肆氓,我揣著相機(jī)與錄音袍祖,去河邊找鬼。 笑死谢揪,一個(gè)胖子當(dāng)著我的面吹牛蕉陋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拨扶,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼寺滚,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了屈雄?” 一聲冷哼從身側(cè)響起村视,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酒奶,沒想到半個(gè)月后蚁孔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惋嚎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年杠氢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片另伍。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鼻百,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出摆尝,到底是詐尸還是另有隱情温艇,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布堕汞,位于F島的核電站勺爱,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏讯检。R本人自食惡果不足惜琐鲁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望人灼。 院中可真熱鬧围段,春花似錦、人聲如沸投放。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至段磨,卻和暖如春取逾,著一層夾襖步出監(jiān)牢的瞬間耗绿,已是汗流浹背苹支。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留误阻,地道東北人债蜜。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像究反,于是被迫代替她去往敵國和親寻定。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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

  • Activity是一個(gè)應(yīng)用組件精耐,用戶可與其提供的屏幕進(jìn)行交互狼速。以執(zhí)行撥打電話,拍攝照片卦停,發(fā)送電子郵件或查看地圖等操...
    DanieX閱讀 1,088評(píng)論 0 4
  • 1. onSaveInstanceState和onRestoreInstanceState基本作用 onSaveI...
    Ten_Minutes閱讀 12,617評(píng)論 2 15
  • 一瓶向胡, 一竹, 一盆惊完, 一草僵芹, 用心愛自己。 終其一生小槐,我們是在上演自己的人生拇派,而非他人,所以凿跳,我們的目光要在自己...
    愛己如生命閱讀 174評(píng)論 0 1
  • 早上還沒起床件豌,接到電話,一開始我以為是鬧鈴控嗜,接聽了:是媽媽打來的苟径,具體內(nèi)容是發(fā)布任務(wù)的,要求給銘帥銘航多穿衣...
    指揮官閱讀 198評(píng)論 0 5
  • 當(dāng)我發(fā)現(xiàn)“叮當(dāng)”時(shí)躬审,它已經(jīng)奄奄一息了棘街。 我看著這個(gè)不可思議的生物,突然產(chǎn)生了憐憫之心承边。甚至冒出了一個(gè)念頭遭殉,如果我把...
    清書_閱讀 545評(píng)論 0 51