通過實現回調方法來管理你的activity的生命周期,對于開發一個健壯而又靈活的應用程序而言是至關重要的。 與其它activity的關聯性、自身的任務和back stack直接影響著一個activity的生命周期。
1、通常activity可能處于三種基本的狀態:
- Resumed
activity在屏幕的前臺并且擁有用戶的焦點。(這個狀態有時也被叫做“running”。) - Paused
另一個activity在前臺并擁有焦點,但是本activity還是可見的。 也就是說,另外一個activity覆蓋在本activity的上面,并且那個activity是部分透明的或沒有覆蓋整個屏幕。 一個paused的activity是完全存活的(Activity 對象仍然保留在內存里,它保持著所有的狀態和成員信息,并且保持與window manager的聯接),但在系統內存嚴重不足的情況下它能被殺死。 - Stopped
本activity被其它的activity完全遮擋住了(本activity目前在后臺)。 一個stopped的activity也仍然是存活的(Activity 對象仍然保留在內存中,它保持著所有的狀態和成員信息,但是不再與window manager聯接了)。 但是,對于用戶而言它已經不再可見了,并且當其它地方需要內存時它將會被殺死。
如果activity被paused或stopped了,則系統可以從內存中刪除它,通過請求finish(調用它的 finish() 方法)或者直接殺死它的進程。 當這個activity被再次啟動時(在被finish或者kill后),它必須被完全重建。
2、實現生命周期回調方法
當一個activity在上述描述的狀態之間轉換時,它將通過各種回調方法來獲得通知。 所有的回調方法都是鉤子(hook),當activity狀態發生改變時你都可以 重寫這些方法來執行對應的工作。 以下的activity提綱包含了所有基本的生命周期方法:
public class ExampleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The activity is being created.
}
@Override
protected void onStart() {
super.onStart();
// The activity is about to become visible.
}
@Override
protected void onResume() {
super.onResume();
// The activity has become visible (it is now "resumed").
}
@Override
protected void onPause() {
super.onPause();
// Another activity is taking focus (this activity is about to be "paused").
}
@Override
protected void onStop() {
super.onStop();
// The activity is no longer visible (it is now "stopped")
}
@Override
protected void onDestroy() {
super.onDestroy();
// The activity is about to be destroyed.
}
}
- activity的完整生存期會在 onCreate() 調用和 onDestroy() 調用之間發生。 你的activity應該在 onCreate() 方法里完成所有“全局global”狀態的設置(比如定義layout), 而在onDestroy() 方法里釋放所有占用的資源。 例如,如果你的activity有一個后臺運行的線程,用于從網絡下載數據,那么你應該在 onCreate() 方法里創建這個線程并且在 onDestroy() 方法里停止這個線程。
- activity的可見生存期會在 onStart() 調用和 onStop() 調用之間發生。在這期間,用戶可在屏幕上看見這個activity并可與之交互。 例如,當一個新的activity啟動后調用了 onStop() 方法,則這個activity就無法被看見了。 在這兩個方法之間,你可以管理那些顯示activity所需的資源。例如,你可以在 onStart() 方法里注冊一個 BroadcastReceiver 用于監控影響用戶界面的改動。并且當用戶不再看到你的顯示內容時,在 onStop() 方法里注銷掉它。 系統會在activity的整個生存期內多次調用 onStart() 和onStop(), 因為activity可能會在顯示和隱藏之間不斷地來回切換。
- activity的前臺生存期會在 onResume() 調用和 onPause() 之間發生。在這期間,activity是位于屏幕上所有其它的activity之前,并且擁有用戶的輸入焦點。 activity可以頻繁地進入和退出前臺——例如, 當設備進入休眠時或者彈出一個對話框時, onPause() 就會被調用。因為這個狀態可能會經常發生轉換,為了避免切換遲緩引起的用戶等待,這兩個方法中的代碼應該相當地輕量化。
同樣的生命周期回調方法已經在下圖中列出了,該表更詳細地描述了每個回調方法,并且指明了每個方法在activity的全生命周期中的位置, 包括回調方法完成后系統是否會殺死這個activity。
3、保存Activity的狀態
當一個activity被paused或者stopped時,activity的狀態可以被保存。 的確如此,因為 Activity 對象在paused或者stopped時仍然被保留在內存之中——它所有的成員信息和當前狀態都仍然存活。 這樣用戶在activity里所作的改動全都還保存著,所以當activity返回到前臺時(當它“resume“),那些改動仍然有效。
不過,如果系統是為了回收內存而銷毀activity,則這個 Activity 對象就會被銷毀,這樣系統就無法簡單地resume一下就能還原完整狀態的activity。 如果用戶要返回到這個activity的話,系統必須重新創建這個Activity 對象。可是用戶并不知道系統是先銷毀activity再重新創建了它的,所以,他很可能希望activity完全保持原樣。 這種情況下,你可以保證activity狀態的相關重要信息都由另一個回調方法保存下來了,此方法讓你能保存activity狀態的相關信息:onSaveInstanceState()。
在activity變得很容易被銷毀之前,系統會調用 onSaveInstanceState()方法。 調用時系統會傳入一個Bundle對象, 你可以利用 putString() 之類的方法,以鍵值對的方式來把activity狀態信息保存到該Bundle對象中。 然后,如果系統殺掉了你的application進程并且用戶又返回到你的activity,系統就會重建activity并將這個 Bundle 傳入onCreate() 和onRestoreInstanceState() 中,你就可以從 Bundle 中解析出已保存信息并恢復activity狀態。如果沒有儲存狀態信息,那么傳入的 Bundle 將為null(當activity第一次被創建時就是如此)。
注意: activity被銷毀之前,并不能確保每次都會調用 onSaveInstanceState() ,因為存在那些不必保存狀態的情況(比如用戶使用BACK鍵離開了你的activity,因為用戶明顯是關了這個activity)。 如果系統要調用 onSaveInstanceState() 方法,那么它通常會在 onStop() 方法之前并且可能是在 onPause() 之前調用。
不過,即使你沒有實現 onSaveInstanceState() 方法,有些activity狀態還是會通過 Activity 類缺省實現的onSaveInstanceState() 方法保存下來。特別的是,缺省為layout中的每個 View 實現了調用相應的onSaveInstanceState() 方法,這允許每一個view提供自己需被保存的信息。 幾乎Android框架下所有的widget都會在適當的時候實現該方法,這樣,任何UI上可見的變化都會自動保存下來,并在activity重建后自動恢復。 例如,EditText widget會保存所有用戶已經輸入的文本, CheckBoxwidget 也會保存是否被選中。你所要做的工作僅僅是為每一個你想要保存其狀態的widget提供一個唯一的ID(就是 android:id 屬性)。如果這個widget沒有ID的話,系統是無法保存它們的狀態的。
通過把android:saveEnabled 設置為"false",或者調用 setSaveEnabled() 方法,你也可以顯式地阻止layout中的某個view保存狀態。 通常不應該禁用保存,不過假如你需要恢復activity UI的各個不同的狀態,也許可以這么做。
盡管缺省實現的 onSaveInstanceState() 方法會保存activity UI的有用信息,你仍然需要覆蓋它來存入更多的信息。 例如,你可能需要保存在activity生命周期中改變的成員變量值(可能是關于UI恢復的值,但是默認情況下,存放這些UI狀態的成員變量值是不會被恢復的)。
因為默認實現的 onSaveInstanceState() 方法已經幫你保存了一些UI的狀態,所以如果你重寫此方法是為了保存更多的狀態信息,那么在執行自己的代碼之前應該確保先調用一次父類的 onSaveInstanceState() 方法。同理,如果重寫 onRestoreInstanceState() 的話,也應該調用一次父類的該方法,這樣缺省的代碼就能正常恢復view的狀態了。
注意:因為 onSaveInstanceState() 并不保證每次都會被調用,所以你應該只用它來記錄activity的一些臨時狀態信息(UI的狀態)——千萬不要用它來保存那些需要長久保存的數據。 替代方案是,你應該在用戶離開activity的時候利用 onPause() 來保存永久性數據(比如那些需要存入數據庫里的數據)。
一個檢測應用程序狀態恢復能力的好方法就是旋轉設備,使得屏幕方向發生改變。 當屏幕的方向改變時,因為要換用符合實際屏幕參數的資源,系統會銷毀并重建這個activity。 正因如此,你的activity能夠在被重建時完整地恢復狀態是非常重要的,因為用戶會在使用應用程序時會頻繁地旋轉屏幕。
4、配置改動后的處理
設備的某些配置可能會在運行時發生變化(比如屏幕方向、鍵盤可用性以及語言)。 當發生這些變化時,Android會重建這個運行中的activity(系統會調用 onDestroy() ,然后再馬上調用 onCreate() )。這種設計有助于應用程序適用新的參數配置,通過把你預置的可替換資源(比如對應各種屏幕方向和尺寸的layout)自動重新裝載進入應用程序的方式來實現。
如果你采取了適當的設計,讓activity能夠正確地處理這些因為屏幕方向而引起的重啟,并能如上所述地恢復activity狀態, 那么你的應用程序將對生命周期中其它的意外事件更具適應能力。
處理這類重啟的最佳方式,就是利用 onSaveInstanceState() 和onRestoreInstanceState() (或者 onCreate() )進行狀態的保存和恢復,如上節所述。
5、多個Activity 一起工作
當activity啟動另一個activity時,它倆生命周期的狀態都會發生轉換。 第一個activity paused并stopped(盡管它也可能不會被stopped,如果它仍然后臺可見的話),而另一個activity是被created。 如果這兩個activity共用了保存在磁盤或其它地方的數據,那么請明白:在第二個activity被created之前,第一個activity還沒有完全被stopped,這點非常重要。 或多或少,第二個activity的啟動進程與第一個activity的關閉進程在時間上會發生重疊。
生命周期回調方法的順序是很明確的,特別是兩個activity位于同一個進程中、一個啟動另一個的時候。 下面就是Aactivity A啟動Activity B時的操作順序:
Activity A的 onPause()方法,如果活動后臺不可見的話,onStop()方法同樣運行,否則不運行。
Activity B的 onCreate() ,onStart() 和onResume() 方法依次運行。(Activity B現在獲得用戶焦點。)
通常情況下的回調順序為:A onPause() -> B onCreate() -> B onStart() -> B onResume() -> A onStop()
以上預設的生命周期回調方法順序使你能夠對一個activity啟動另一個activity時的轉換信息進行管理。 例如,如果第一個activity停止時你須寫入數據庫以便后續的activity可以讀取數據,那么你應該在 onPause() 方法而不是 onStop() 方法里寫入數據庫。
原文鏈接
http://www.android-doc.com/guide/components/activities.html#