轉自:http://blog.csdn.net/android_tutor/article/details/5772285html
你們好,今天給你們詳解一下Android中Activity的生命週期,我在前面也曾經講過這方面的內容,可是像網上大多數文章同樣,基本都是翻譯Android API,過於籠統,相信你們看了,會有一點點的幫助 ,可是還不能徹底吃透,因此我今天特地在從新總結一下.java
首先看一下Android api中所提供的Activity生命週期圖(不明白的,能夠看完整篇文章,在回頭看一下這個圖,你會明白的):android
Activity實際上是繼承了ApplicationContext這個類,咱們能夠重寫如下方法,以下代碼:api
- 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.app
第二步:修改ActivityDemo.java(我這裏從新寫了以上的七種方法,主要用Log打印),代碼以下:ide
- 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視窗以下:ui
BACK鍵:spa
當咱們按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;
-
- 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~~~");
- }
-
- @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~~~");
- }
-
-
- @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
圖2
從圖2所示的Activity生命週期不難看出,在這個圖中包含了兩層循環,
第一層循環是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被系統結束