Activity 的運行時生命周期模型

由於在Android中,進程的生命周期大多數時候是由系統管理的;另外也由於手機應用的一些特殊性,所以我們需要更多的去關註各個Android Component的運行時生命周期模型。(所謂手機應用的特殊性主要是指這樣2點: 1. 手機應用的大多數情況下我們隻能在手機上看到一個程序的一個界面 ,用戶除瞭通過程序界面上的功能按鈕來在不同的窗體間切換,還可以通過Back鍵和Home鍵來返回上一個窗口,而用戶使用Back或者Home的時機是非常不確定的,任何時候用戶都可以使用Home或Back來強行切換當前的界面。 2. 往往手機上一些特殊的事件發生也會強制的改變當前用戶所處的操作狀態,例如無論任何情況,在手機來電時,系統都會優先顯示電話接聽界面。)瞭解這些Component的生命周期模型一方面是讓我們對軟件在手機中的運行情況做到心中有數,更重要的,對於程序開發來說,生命周期中的每一個關鍵事件都會有我們可以覆寫於各種Component對應基類型的事件處理方法,瞭解各Component的生命周期就是讓我們在開發程序時明白我們該怎樣去編寫各種事件的處理代碼。例如Activity的Create,就會有對應的事件處理函數onCreate,我們可以從Activity基類覆寫這個事件處理函數完成我們需要的相關事件處理:
public class actMain extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
…… //我們的事件處理代碼
}
……

這篇Post我們就來看看最常用的Activity的運行時生命周期模型(Service的運行時生命周期模型在下一篇講述瞭如何啟動一個Service並和其通信後再做描述)。 Activity的生命周期模型在Google提供的官方文檔上有比較詳細的一個圖示(請自行翻墻查看)。其一共包含7個我們需要關心的關鍵事件,下面對其分別詳細說明(文字中的粗體字表示後文中會經常用到的概念在第一次出現時會給出解釋,之後後文不再詳細說明):

1. void onCreate(Bundle savedInstanceState)
當Activity被第首次加載時執行。我們新啟動一個程序的時候其主窗體的onCreate事件就會被執行。如果Activity被銷毀後(onDestroy後),再重新加載進Task時,其onCreate事件也會被重新執行。註意這裡的參數savedInstanceState(Bundle類型是一個鍵值對集合,大傢可以看成是.Net中的Dictionary)是一個很有用的設計,由於前面已經說到的手機應用的特殊性,一個Activity很可能被強制交換到後臺(交換到後臺就是指該窗體不再對用戶可見,但實際上又還是存在於某個Task中的,比如一個新的Activity壓入瞭當前的Task從而“遮蓋”住瞭當前的Activity,或者用戶按瞭Home鍵回到桌面,又或者其他重要事件發生導致新的Activity出現在當前Activity之上,比如來電界面),而如果此後用戶在一段時間內沒有重新查看該窗體(Android通過長按Home鍵可以選擇最近運行的6個程序,或者用戶直接再次點擊程序的運行圖標,如果窗體所在的Task和進程沒有被系統銷毀,則不用重新加載Process, Task和Task中的Activity, 直接重新顯示Task頂部的Activity, 這就稱之為重新查看某個程序的窗體),該窗體連同其所在的Task和Process則可能已經被系統自動銷毀瞭,此時如果再次查看該窗體,則要重新執行onCreate事件初始化窗體。而這個時候我們可能希望用戶繼續上次打開該窗體時的操作狀態進行操作,而不是一切從頭開始。例如用戶在編輯短信時突然來電,接完電話後用戶又去做瞭一些其他的事情,比如保存來電號碼到聯系人,而沒有立即回到短信編輯界面,導致瞭短信編輯界面被銷毀,當用戶重新進入短信程序時他可能希望繼續上次的編輯。這種情況我們就可以覆寫Activity的void onSaveInstanceState(Bundle outState)事件,通過向outState中寫入一些我們需要在窗體銷毀前保存的狀態或信息,這樣在窗體重新執行onCreate的時候,則會通過savedInstanceState將之前保存的信息傳遞進來,此時我們就可以有選擇的利用這些信息來初始化窗體,而不是一切從頭開始。
2. void onStart()
onCreate事件之後執行。或者當前窗體被交換到後臺後,在用戶重新查看窗體前已經過去瞭一段時間,窗體已經執行瞭onStop事件,但是窗體和其所在進程並沒有被銷毀,用戶再次重新查看窗體時會執行onRestart事件,之後會跳過onCreate事件,直接執行窗體的onStart事件。
3. void onResume()
onStart事件之後執行。或者當前窗體被交換到後臺後,在用戶重新查看窗體時,窗體還沒有被銷毀,也沒有執行過onStop事件(窗體還繼續存在於Task中),則會跳過窗體的onCreate和onStart事件,直接執行onResume事件。
4. void onPause()
窗體被交換到後臺時執行。
5. void onStop()
onPause事件之後執行。如果一段時間內用戶還沒有重新查看該窗體,則該窗體的onStop事件將會被執行;或者用戶直接按瞭Back鍵,將該窗體從當前Task中移除,也會執行該窗體的onStop事件。
6. void onRestart()
onStop事件執行後,如果窗體和其所在的進程沒有被系統銷毀,此時用戶又重新查看該窗體,則會執行窗體的onRestart事件,onRestart事件後會跳過窗體的onCreate事件直接執行onStart事件。
7. void onDestroy()
Activity被銷毀的時候執行。在窗體的onStop事件之後,如果沒有再次查看該窗體,Activity則會被銷毀。

最後用一個實際的例子來說明Activity的各個生命周期。假設有一個程序由2個Activity A和B組成,A是這個程序的啟動界面。當用戶啟動程序時,Process和默認的Task分別被創建,接著A被壓入到當前的Task中,依次執行瞭onCreate, onStart, onResume事件被呈現給瞭用戶;此時用戶選擇A中的某個功能開啟界面B,界面B被壓入當前Task遮蓋住瞭A,A的onPause事件執行,B的onCreate, onStart, onResume事件執行,呈現瞭界面B給用戶;用戶在界面B操作完成後,使用Back鍵回到界面A,界面B不再可見,界面B的onPause, onStop, onDestroy執行,A的onResume事件被執行,呈現界面A給用戶。此時突然來電,界面A的onPause事件被執行,電話接聽界面被呈現給用戶,用戶接聽完電話後,又按瞭Home鍵回到桌面,打開另一個程序“聯系人”,添加瞭聯系人信息又做瞭一些其他的操作,此時界面A不再可見,其onStop事件被執行,但並沒有被銷毀。此後用戶重新從菜單中點擊瞭我們的程序,由於A和其所在的進程和Task並沒有被銷毀,A的onRestart和onStart事件被執行,接著A的onResume事件被執行,A又被呈現給瞭用戶。用戶這次使用完後,按Back鍵返回到桌面,A的onPause, onStop被執行,隨後A的onDestroy被執行,由於當前Task中已經沒有任何Activity,A所在的Process的重要程度被降到很低,很快A所在的Process被系統結束。

摘自 sql_help的專欄

發佈留言