zz Android -- Activity的銷燬和重建

本文將介紹Activity的銷燬和重建。銷燬分兩種:第一種是正常的銷燬,好比用戶按下Back按鈕或者是activity本身調用了finish()方法;另外一種是因爲activity處於stopped狀態,而且它長期未被使用,或者前臺的activity須要更多的資源,這些狀況下系統就會關閉後臺的進程,以恢復一些內存。ide

 

兩種銷燬

第一種是正常的銷燬,好比用戶按下Back按鈕或者是activity本身調用了finish()方法;函數

另外一種是因爲activity處於stopped狀態,而且它長期未被使用,或者前臺的activity須要更多的資源,這些狀況下系統就會關閉後臺的進程,以恢復一些內存。編碼

須要注意的是這其中有一種狀況就是屏幕旋轉的問題,當用戶旋轉手機屏幕,每一次都會致使activity的銷燬和從新創建。spa

在第二種狀況下,儘管實際的activity實例已經被銷燬,可是系統仍然記得它的存在,當用戶返回到它的時候,系統會建立出一個新的實例來代替它,這裏須要利用舊實例被銷燬時候存下來的數據。這些數據被稱爲「instance state」,是一個存在Bundle對象中的鍵值對集合。rest

缺省狀態下,系統會把每個View對象保存起來(好比EditText對象中的文本,ListView中的滾動條位置等),即若是activity實例被銷燬和重建,那麼不須要你編碼,layout狀態會恢復到前次狀態。對象

可是若是你的activity須要恢復更多的信息,好比成員變量信息,則須要本身動手寫了。blog

onSaveInstanceState()

若是要存儲額外的數據,必須覆寫回調函數onSaveInstanceState().進程

系統會在用戶離開activity的時候調用這個函數,而且傳遞給它一個Bundle object,若是系統稍後須要重建這個activity實例,它會傳遞同一個Bundle object到onRestoreInstanceState() 和 onCreate() 方法中去。內存

1

當系統中止activity時,它會調用onSaveInstanceState()(過程1),若是activity被銷燬了,可是須要建立一樣的實例,系統會把過程1中的狀態數據傳給onCreate()和onRestoreInstanceState()(圖中標出的2和3)。資源

存儲Activity狀

當系統中止activity時,系統會調用onSaveInstanceState(),狀態信息會以鍵值對的形式存儲下來。

默認的實現中存儲了activity的view系列的狀態,好比文本和滾動條位置等。

要存儲額外的信息,必須本身實現onSaveInstanceState(),而且給Bundle object加上鍵值對。

  1. static final String STATE_SCORE = "playerScore"; 
  2. static final String STATE_LEVEL = "playerLevel"; 
  3. ... 
  4.  
  5. @Override 
  6. public void onSaveInstanceState(Bundle savedInstanceState) { 
  7.     // Save the user's current game state 
  8.     savedInstanceState.putInt(STATE_SCORE, mCurrentScore); 
  9.     savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel); 
  10.      
  11.     // Always call the superclass so it can save the view hierarchy state 
  12.     super.onSaveInstanceState(savedInstanceState); 

要記得調用基類的實現,以實現默認的實現。

恢復Activity狀態

當activity重建時,須要根據Bundle中的狀態信息數據恢復activity。onCreate() 和onRestoreInstanceState()回調函數都會接收到這個Bundle。

由於每次建立新的activity實例的或重建一個實例的時候都會調用onCreate()方法,因此必須先檢查是否Bundle是null,若是是null,則代表是要建立一個全新的對象,而不是重建一個上次被銷燬的對象。

好比onCreate()方法能夠這麼寫:

  1. @Override 
  2. protected void onCreate(Bundle savedInstanceState) { 
  3.     super.onCreate(savedInstanceState); // Always call the superclass first 
  4.     
  5.     // Check whether we're recreating a previously destroyed instance 
  6.     if (savedInstanceState != null) { 
  7.         // Restore value of members from saved state 
  8.         mCurrentScore = savedInstanceState.getInt(STATE_SCORE); 
  9.         mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); 
  10.     } else { 
  11.         // Probably initialize members with default values for a new instance 
  12.     } 
  13.     ... 

除了在onCreate()中恢復狀態外,也能夠選擇在onRestoreInstanceState()中實現,這個函數在onStart()以後調用。

只有在有數據要恢復的時候系統會調用onRestoreInstanceState(),因此沒必要檢查Bundle是否爲null。

  1. public void onRestoreInstanceState(Bundle savedInstanceState) { 
  2.     // Always call the superclass so it can restore the view hierarchy 
  3.     super.onRestoreInstanceState(savedInstanceState); 
  4.     
  5.     // Restore state members from saved instance 
  6.     mCurrentScore = savedInstanceState.getInt(STATE_SCORE); 
  7.     mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); 

此處也要注意,不要忘記調用基類實現。

相關文章
相關標籤/搜索