Android -- Activity的銷毀和重建
兩種銷毀
***種是正常的銷毀,比如用戶按下Back按鈕或者是activity自己調(diào)用了finish()方法;
另一種是由于activity處于stopped狀態(tài),并且它長期未被使用,或者前臺的activity需要更多的資源,這些情況下系統(tǒng)就會關(guān)閉后臺的進程,以恢復(fù)一些內(nèi)存。
需要注意的是這其中有一種情況就是屏幕旋轉(zhuǎn)的問題,當(dāng)用戶旋轉(zhuǎn)手機屏幕,每一次都會導(dǎo)致activity的銷毀和重新建立。
在第二種情況下,盡管實際的activity實例已經(jīng)被銷毀,但是系統(tǒng)仍然記得它的存在,當(dāng)用戶返回到它的時候,系統(tǒng)會創(chuàng)建出一個新的實例來代替它,這里需要利用舊實例被銷毀時候存下來的數(shù)據(jù)。這些數(shù)據(jù)被稱為“instance state”,是一個存在Bundle對象中的鍵值對集合。
缺省狀態(tài)下,系統(tǒng)會把每一個View對象保存起來(比如EditText對象中的文本,ListView中的滾動條位置等),即如果activity實例被銷毀和重建,那么不需要你編碼,layout狀態(tài)會恢復(fù)到前次狀態(tài)。
但是如果你的activity需要恢復(fù)更多的信息,比如成員變量信息,則需要自己動手寫了。
onSaveInstanceState()
如果要存儲額外的數(shù)據(jù),必須覆寫回調(diào)函數(shù)onSaveInstanceState().
系統(tǒng)會在用戶離開activity的時候調(diào)用這個函數(shù),并且傳遞給它一個Bundle object,如果系統(tǒng)稍后需要重建這個activity實例,它會傳遞同一個Bundle object到onRestoreInstanceState() 和 onCreate() 方法中去。
當(dāng)系統(tǒng)停止activity時,它會調(diào)用onSaveInstanceState()(過程1),如果activity被銷毀了,但是需要創(chuàng)建同樣的實例,系統(tǒng)會把過程1中的狀態(tài)數(shù)據(jù)傳給onCreate()和onRestoreInstanceState()(圖中標(biāo)出的2和3)。
存儲Activity狀
當(dāng)系統(tǒng)停止activity時,系統(tǒng)會調(diào)用onSaveInstanceState(),狀態(tài)信息會以鍵值對的形式存儲下來。
默認(rèn)的實現(xiàn)中存儲了activity的view系列的狀態(tài),比如文本和滾動條位置等。
要存儲額外的信息,必須自己實現(xiàn)onSaveInstanceState(),并且給Bundle object加上鍵值對。
- 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 state
- super.onSaveInstanceState(savedInstanceState);
- }
要記得調(diào)用基類的實現(xiàn),以實現(xiàn)默認(rèn)的實現(xiàn)。
恢復(fù)Activity狀態(tài)
當(dāng)activity重建時,需要根據(jù)Bundle中的狀態(tài)信息數(shù)據(jù)恢復(fù)activity。onCreate() 和onRestoreInstanceState()回調(diào)函數(shù)都會接收到這個Bundle。
因為每次創(chuàng)建新的activity實例的或重建一個實例的時候都會調(diào)用onCreate()方法,所以必須先檢查是否Bundle是null,如果是null,則表明是要創(chuàng)建一個全新的對象,而不是重建一個上次被銷毀的對象。
比如onCreate()方法可以這么寫:
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState); // Always call the superclass first
- // Check whether we're recreating a previously destroyed instance
- if (savedInstanceState != null) {
- // Restore value of members from saved state
- mCurrentScore = 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()中實現(xiàn),這個函數(shù)在onStart()之后調(diào)用。
只有在有數(shù)據(jù)要恢復(fù)的時候系統(tǒng)會調(diào)用onRestoreInstanceState(),所以不必檢查Bundle是否為null。
- public void onRestoreInstanceState(Bundle savedInstanceState) {
- // Always call the superclass so it can restore the view hierarchy
- super.onRestoreInstanceState(savedInstanceState);
- // Restore state members from saved instance
- mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
- mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
- }
此處也要注意,不要忘記調(diào)用基類實現(xiàn)。