重新创建Activity
?
Activity的重新創(chuàng)建
關(guān)于Activity生命周期的討論見(jiàn)本博客上次有關(guān)的博文:
????? http://www.cnblogs.com/mengdd/archive/2012/12/01/2797784.html
本篇博文要講的是activity重建的情況,以及這個(gè)過(guò)程中的數(shù)據(jù)存儲(chǔ)和恢復(fù)。
?
Activity的銷毀和重建
Activity的銷毀分為兩種:
第一種是正常的銷毀,比如用戶按下Back按鈕或者是activity自己調(diào)用了finish()方法;
另一種是由于activity處于stopped狀態(tài),并且它長(zhǎng)期未被使用,或者前臺(tái)的activity需要更多的資源,這些情況下系統(tǒng)就會(huì)關(guān)閉后臺(tái)的進(jìn)程,以恢復(fù)一些內(nèi)存。
需要注意的是這其中有一種情況就是屏幕旋轉(zhuǎn)的問(wèn)題,當(dāng)用戶旋轉(zhuǎn)手機(jī)屏幕,每一次都會(huì)導(dǎo)致activity的銷毀和重新建立。
在第二種情況下,盡管實(shí)際的activity實(shí)例已經(jīng)被銷毀,但是系統(tǒng)仍然記得它的存在,當(dāng)用戶返回到它的時(shí)候,系統(tǒng)會(huì)創(chuàng)建出一個(gè)新的實(shí)例來(lái)代替它,這里需要利用舊實(shí)例被銷毀時(shí)候存下來(lái)的數(shù)據(jù)。這些數(shù)據(jù)被稱為“instance state”,是一個(gè)存在Bundle對(duì)象中的鍵值對(duì)集合。
缺省狀態(tài)下,系統(tǒng)會(huì)把每一個(gè)View對(duì)象保存起來(lái)(比如EditText對(duì)象中的文本,ListView中的滾動(dòng)條位置等),即如果activity實(shí)例被銷毀和重建,那么不需要你編碼,layout狀態(tài)會(huì)恢復(fù)到前次狀態(tài)。
但是如果你的activity需要恢復(fù)更多的信息,比如成員變量信息,則需要自己動(dòng)手寫了。
如果要存儲(chǔ)額外的數(shù)據(jù),必須覆寫回調(diào)函數(shù)onSaveInstanceState().
系統(tǒng)會(huì)在用戶離開(kāi)activity的時(shí)候調(diào)用這個(gè)函數(shù),并且傳遞給它一個(gè)Bundle object,如果系統(tǒng)稍后需要重建這個(gè)activity實(shí)例,它會(huì)傳遞同一個(gè)Bundle object到onRestoreInstanceState() 和 onCreate() 方法中去。
? ? ? ? ? ? ? ? ? ? ? ? ?
? 當(dāng)系統(tǒng)停止activity時(shí),它會(huì)調(diào)用onSaveInstanceState()(過(guò)程1),如果activity被銷毀了,但是需要?jiǎng)?chuàng)建同樣的實(shí)例,系統(tǒng)會(huì)把過(guò)程1中的狀態(tài)數(shù)據(jù)傳給onCreate()和onRestoreInstanceState()(圖中標(biāo)出的2和3)。
?
存儲(chǔ)Activity狀態(tài)
當(dāng)系統(tǒng)停止activity時(shí),系統(tǒng)會(huì)調(diào)用onSaveInstanceState(),狀態(tài)信息會(huì)以鍵值對(duì)的形式存儲(chǔ)下來(lái)。
默認(rèn)的實(shí)現(xiàn)中存儲(chǔ)了activity的view系列的狀態(tài),比如文本和滾動(dòng)條位置等。
要存儲(chǔ)額外的信息,必須自己實(shí)現(xiàn)onSaveInstanceState(),并且給Bundle object加上鍵值對(duì)。
比如:
?
Save Activity State static final String STATE_SCORE = "playerScore"; static final String STATE_LEVEL = "playerLevel"; ...@Override public void onSaveInstanceState(Bundle savedInstanceState) {// Save the user's current game state savedInstanceState.putInt(STATE_SCORE, mCurrentScore);savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);// Always call the superclass so it can save the view hierarchy statesuper.onSaveInstanceState(savedInstanceState); }要記得調(diào)用基類的實(shí)現(xiàn),以實(shí)現(xiàn)默認(rèn)的實(shí)現(xiàn)。
?
恢復(fù)Activity狀態(tài)
當(dāng)activity重建時(shí),需要根據(jù)Bundle中的狀態(tài)信息數(shù)據(jù)恢復(fù)activity。
onCreate() 和onRestoreInstanceState()回調(diào)函數(shù)都會(huì)接收到這個(gè)Bundle。
因?yàn)?span style="color:#ff0000;">每次創(chuàng)建新的activity實(shí)例的或重建一個(gè)實(shí)例的時(shí)候都會(huì)調(diào)用onCreate()方法,所以必須先檢查是否Bundle是null,如果是null,則表明是要?jiǎng)?chuàng)建一個(gè)全新的對(duì)象,而不是重建一個(gè)上次被銷毀的對(duì)象。
比如onCreate()方法可以這么寫:
?
onCreate() 方法 @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); // Always call the superclass first// Check whether we're recreating a previously destroyed instanceif (savedInstanceState != null) {// Restore value of members from saved statemCurrentScore = savedInstanceState.getInt(STATE_SCORE);mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);} else {// Probably initialize members with default values for a new instance }... }?
除了在onCreate()中恢復(fù)狀態(tài)外,也可以選擇在onRestoreInstanceState()中實(shí)現(xiàn),這個(gè)函數(shù)在onStart()之后調(diào)用。
只有在有數(shù)據(jù)要恢復(fù)的時(shí)候系統(tǒng)會(huì)調(diào)用onRestoreInstanceState(),所以不必檢查Bundle是否為null。
?
onRestoreInstanceState()方法 public void onRestoreInstanceState(Bundle savedInstanceState) {// Always call the superclass so it can restore the view hierarchysuper.onRestoreInstanceState(savedInstanceState);// Restore state members from saved instancemCurrentScore = savedInstanceState.getInt(STATE_SCORE);mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); }此處也要注意,不要忘記調(diào)用基類實(shí)現(xiàn)。
?
參考資料:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
?
?
總結(jié)
以上是生活随笔為你收集整理的重新创建Activity的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: poj 3041 Asteroids
- 下一篇: 关于 strftime 的使用