轉自:http://blog.csdn.net/android_tutor/article/details/5772285
大家好,今天給大家詳解一下Android中Activity的生命周期,我在前面也曾經講過這方面的內容,但是像網上大多數文章一樣,基本都是翻譯Android API,過於籠統,相信大家看了,會有一點點的幫助 ,但是還不能完全吃透,所以我今天特意在重新總結一下.
首先看一下Android api中所提供的Activity生命周期圖(不明白的,可以看完整篇文章,在回頭看一下這個圖,你會明白的):
Activity其實是繼承了ApplicationContext這個類,我們可以重寫以下方法,如下代碼:
- public class Activity extends ApplicationContext {
- protected void onCreate(Bundle savedInstanceState);
- protected void onStart();
- protected void onRestart();
- protected void onResume();
- protected void onPause();
- protected void onStop();
- protected void onDestroy();
- }
為了便於大家更好的理解,我簡單的寫了一個Demo,不明白Activity周期的朋友們,可以親手實踐一下,大家按照我的步驟來。
第一步:新建一個Android工程,我這里命名為ActivityDemo.
第二步:修改ActivityDemo.java(我這里重新寫了以上的七種方法,主要用Log打印),代碼如下:
- package com.tutor.activitydemo;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- public class ActivityDemo extends Activity {
- private static final String TAG = "ActivityDemo";
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- Log.e(TAG, "start onCreate~~~");
- }
- @Override
- protected void onStart() {
- super.onStart();
- Log.e(TAG, "start onStart~~~");
- }
- @Override
- protected void onRestart() {
- super.onRestart();
- Log.e(TAG, "start onRestart~~~");
- }
- @Override
- protected void onResume() {
- super.onResume();
- Log.e(TAG, "start onResume~~~");
- }
- @Override
- protected void onPause() {
- super.onPause();
- Log.e(TAG, "start onPause~~~");
- }
- @Override
- protected void onStop() {
- super.onStop();
- Log.e(TAG, "start onStop~~~");
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- Log.e(TAG, "start onDestroy~~~");
- }
- }
第三步:運行上述工程,效果圖如下(沒什么特別的):
核心在Logcat視窗里,如果你還不會用Logcat你可以看一下我的這篇文章 Log圖文詳解(Log.v,Log.d,Log.i,Log.w,Log.e) ,我們打開應用時先后執行了onCreate()->onStart()->onResume三個方法,看一下LogCat視窗如下:
BACK鍵:
當我們按BACK鍵時,我們這個應用程序將結束,這時候我們將先后調用onPause()->onStop()->onDestory()三個方法,如下圖所示:
HOME鍵:
當我們打開應用程序時,比如瀏覽器,我正在瀏覽NBA新聞,看到一半時,我突然想聽歌,這時候我們會選擇按HOME鍵,然后去打開音樂應用程序,而當我們按HOME的時候,Activity先后執行了onPause()->onStop()這兩個方法,這時候應用程序並沒有銷毀。如下圖所示:
而當我們再次啟動ActivityDemo應用程序時,則先后分別執行了onRestart()->onStart()->onResume()三個方法,如下圖所示:
這里我們會引出一個問題,當我們按HOME鍵,然后再進入ActivityDemo應用時,我們的應用的狀態應該是和按HOME鍵之前的狀態是一樣的,同樣為了方便理解,在這里我將ActivityDemo的代碼作一些修改,就是增加一個EditText。
第四步:修改main.xml布局文件(增加了一個EditText),代碼如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
- <EditText
- android:id="@+id/editText"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
第五步:然后其他不變,運行ActivityDemo程序,在EditText里輸入如"Frankie"字符串(如下圖:)
這時候,大家可以按一下HOME鍵,然后再次啟動ActivityDemo應用程序,這時候EditText里並沒有我們輸入的"Frankie"字樣,如下圖:
這顯然不能稱得一個合格的應用程序,所以我們需要在Activity幾個方法里自己實現,如下第六步所示:
第六步修改ActivityDemo.java代碼如下:
- package com.tutor.activitydemo;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.widget.EditText;
- public class ActivityDemo extends Activity {
- private static final String TAG = "ActivityDemo";
- private EditText mEditText;
- //定義一個String 類型用來存取我們EditText輸入的值
- private String mString;
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mEditText = (EditText)findViewById(R.id.editText);
- Log.e(TAG, "start onCreate~~~");
- }
- @Override
- protected void onStart() {
- super.onStart();
- Log.e(TAG, "start onStart~~~");
- }
- //當按HOME鍵時,然后再次啟動應用時,我們要恢復先前狀態
- @Override
- protected void onRestart() {
- super.onRestart();
- mEditText.setText(mString);
- Log.e(TAG, "start onRestart~~~");
- }
- @Override
- protected void onResume() {
- super.onResume();
- Log.e(TAG, "start onResume~~~");
- }
- //當我們按HOME鍵時,我在onPause方法里,將輸入的值賦給mString
- @Override
- protected void onPause() {
- super.onPause();
- mString = mEditText.getText().toString();
- Log.e(TAG, "start onPause~~~");
- }
- @Override
- protected void onStop() {
- super.onStop();
- Log.e(TAG, "start onStop~~~");
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- Log.e(TAG, "start onDestroy~~~");
- }
- }
第七步:重新運行ActivityDemo程序,重復第五步操作,當我們按HOME鍵時,再次啟動應用程序時,EditText里有上次輸入的"Frankie"字樣,如下圖如示:
OK,大功基本告成,這時候大家可以在回上面看一下Activity生命周期圖,我想大家應該完全了解了Activity的生命周期了,不知道你了解了沒?
==以下內容來源:======
http://blog.chinaunix.net/uid-24410388-id-3855498.html
三個循環
提供兩個關於Activity的生命周期模型圖示幫助理解:

圖1

第一層循環是onPause -> onResume -> onPause,
第二層循環是onStop -> onRestart -> onStart -> onResume -> onPause -> onStop。我們可以將這兩層循環看成是整合Activity生命周期中的子生命周期。第一層循環稱為焦點生命周期,第二層循環稱為可視生命周期。也就是說,第一層循環在Activity焦點的獲得與失去的過程中循環,在這一過程中,Activity始終是可見的。而第二層循環是在Activity可見與不可見的過程中循環,在這個過程中伴隨着Activity的焦點的獲得與失去。也就是說,Activity首先會被顯示,然后會獲得焦點,接着失去焦點,最后由於彈出其他的Activity,使當前的Activity變成不可見。因此,Activity有如下3種生命周期:
整體生命周期:onCreate -> ... ... -> onDestroy。
可視生命周期:onStop -> ... ... -> onPause。
焦點生命周期:onPause -> onResume。
四個階段
上面7個生命周期方法分別在4個階段按着一定的順序進行調用,這4個階段如下:
開始Activity:在這個階段依次執行3個生命周期方法:onCreate、onStart和onResume。
Activity失去焦點:如果在Activity獲得焦點的情況下進入其他的Activity或應用程序,這時當前的Activity會失去焦點。在這一階段,會依次執行onPause和onStop方法。
Activity重新獲得焦點:如果Activity重新獲得焦點,會依次執行3個生命周期方法:onRestart、onStart和onResume。
關閉Activity:當Activity被關閉時系統會依次執行3個生命周期方法:onPause、onStop和onDestroy。
如果在這4個階段執行生命周期方法的過程中不發生狀態的改變,那么系統會按着上面的描述依次執行這4個階段中的生命周期方法,但如果在執行的過程中改變了狀態,系統會按着更復雜的方式調用生命周期方法。
在執行的過程中可以改變系統的執行軌跡的生命周期方法是onPause和onStop。如果在執行onPause方法的過程中Activity重新獲得了焦點,然后又失去了焦點。系統將不會再執行onStop方法,而是按着如下的順序執行相應的生命周期方法:
onPause -> onResume-> onPause
如果在執行onStop方法的過程中Activity重新獲得了焦點,然后又失去了焦點。系統將不會執行onDestroy方法,而是按着如下的順序執行相應的生命周期方法:
onStop -> onRestart -> onStart -> onResume -> onPause -> onStop
在圖2所示的Activity生命周期里可以看出,系統在終止應用程序進程時會調用onPause、onStop和onDesktroy方法。而onPause方法排在了最前面,也就是說,Activity在失去焦點時就可能被終止進程,而onStop和onDestroy方法可能沒有機會執行。因此,應該在onPause方法中保存當前Activity狀態,這樣才能保證在任何時候終止進程時都可以執行保存Activity狀態的代碼。
七個方法
下面對其分別詳細說明(文字中的粗體字表示后文中會經常用到的概念在第一次出現時會給出解釋,之后后文不再詳細說明):
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和進程沒有被系統銷毀,則不用重新加載,直接重新顯示Task頂部的Activity,這就稱之為重新查看某個程序的窗體),該窗體連同其所在的 Task和Process則可能已經被系統自動銷毀了,此時如果再次查看該窗體,則要重新執行 onCreate事件初始化窗體。而這個時候我們可能希望用戶繼續上次打開該窗體時的操作狀態進行操作,而不是一切從頭開始。例如用戶在編輯短信時突然來電,接完電話后用戶又去做了一些其他的事情,比如保存來電號碼到聯系人,而沒有立即回到短信編輯界面,導致了短信編輯界面被銷毀,當用戶重新進入短信程序時他可能希望繼續上次的編輯。這種情況我們就可以覆寫Activity的void onSaveInstanceState(Bundle outState)事件,通過向outState中寫入一些我們需要在窗體銷毀前保存的狀態或信息,這樣在窗體重新執行onCreate的時候,則會通過 savedInstanceState將之前保存的信息傳遞進來,此時我們就可以有選擇的利用這些信息來初始化窗體,而不是一切從頭開始。
2. void onStart() activity變為在屏幕上對用戶可見時調用。
onCreate事件之后執行。或者當前窗體被交換到后台后,在用戶重新查看窗體前已經過去了一段時間,窗體已經執行了onStop事件,但是窗體和其所在進程並沒有被銷毀,用戶再次重新查看窗體時會執行onRestart事件,之后會跳過onCreate事件,直接執行窗體的onStart事件。
3. void onResume() activity開始與用戶交互時調用(無論是啟動還是重新啟動一個活動,該方法總是被調用的)。
onStart事件之后執行。或者當前窗體被交換到后台后,在用戶重新查看窗體時,窗體還沒有被銷毀,也沒有執行過onStop事件(窗體還繼續存在於Task中),則會跳過窗體的onCreate和onStart事件,直接執行onResume事件。
4. void onPause() activity被暫停或收回cpu和其他資源時調用,該方法用於保存活動狀態的,也是保護現場,壓棧吧!
窗體被交換到后台時執行。
5. void onStop() activity被停止並轉為不可見階段及后續的生命周期事件時調用。
onPause事件之后執行。如果一段時間內用戶還沒有重新查看該窗體,則該窗體的onStop事件將會被執行;或者用戶直接按了Back鍵,將該窗體從當前Task中移除,也會執行該窗體的onStop事件。
6. void onRestart() 重新啟動activity時調用。該活動仍在棧中,而不是啟動新的活動。
onStop事件執行后,如果窗體和其所在的進程沒有被系統銷毀,此時用戶又重新查看該窗體,則會執行窗體的onRestart事件,onRestart事件后會跳過窗體的onCreate事件直接執行onStart事件。
7. void onDestroy() activity被完全從系統內存中移除時調用,該方法被調用可能是因為有人直接調用onFinish()方法或者系統決定停止該活動以釋放資源!
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被系統結束