天天看點

Activity詳解(生命周期、以各種方式啟動Activity、狀态儲存,完全退出等)

    簡單的說:activity就是布滿整個視窗或者懸浮于其他視窗上的互動界面。在一個應用程式中通常由多個activity構成,都會在manifest.xml中指定一個主的activity,如下設定

<actionandroid:name="android.intent.action.main" />

當程式第一次運作時使用者就會看這個activity,這個activity可以通過啟動其他的activity進行相關操作。當啟動其他的activity時這個目前的這個activity将會停止,新的activity将會壓入棧中,同時擷取使用者焦點,這時就可在這個activity上操作了。都知道棧是先進後出的原則,那麼當使用者按back鍵時,目前的這個activity銷毀,前一個activity重新恢複。

先看下圖:

Activity詳解(生命周期、以各種方式啟動Activity、狀态儲存,完全退出等)

這個圖不再多說什麼,下面我們通過一個執行個體來說明問題。建立工程,編寫如下代碼:

[java] view

plain copy

 print?

<span style="font-size:18px;">package com.android.ttx.actiitylifedemo;  

import android.app.activity;  

import android.os.bundle;  

import android.util.log;  

import android.view.keyevent;  

public class activitylifedemo extends activity {  

    private final static string tag="activitylifedemo";  

    @override  

    public void oncreate(bundle savedinstancestate) {  

        super.oncreate(savedinstancestate);  

        setcontentview(r.layout.main);  

        log.i(tag, "oncreate");  

    }  

    protected void onstart() {  

        log.i(tag, "onstart");  

        super.onstart();  

    protected void onrestart() {  

        log.i(tag, "onrestart");  

        super.onrestart();  

    protected void onresume() {  

        log.i(tag, "onresume");  

        super.onresume();  

    protected void onpause() {  

        log.i(tag, "onpause");  

        super.onpause();  

    protected void onstop() {  

        log.i(tag, "onstop");  

        super.onstop();  

    protected void ondestroy() {  

        log.i(tag, "ondestroy");  

        super.ondestroy();  

}  

</span>  

代碼很簡單,隻涉及到一個activity,一些使用者的操作,我們通過記錄操作和列印日志的方式來看看activity的生命周期過程。

1、  運作

看到如下列印日志:

08-31 08:46:53.916: info/activitylifedemo(312): oncreate

08-31 08:46:53.916: info/activitylifedemo(312): onstart

08-31 08:46:53.916: info/activitylifedemo(312): onresume

2、按下傳回按鍵: 

08-31 09:29:57.396: info/activitylifedemo(354): onpause

08-31 09:29:58.216: info/activitylifedemo(354): onstop

08-31 09:29:58.216: info/activitylifedemo(354): ondestroy

3、長按home鍵,彈出最近打開過的應用程式,點選activitylifedemo

08-31 08:51:46.916: info/activitylifedemo(312): oncreate

08-31 08:51:46.916: info/activitylifedemo(312): onstart

08-31 08:51:46.936: info/activitylifedemo(312): onresume

4、按home鍵

08-31 08:53:32.676: info/activitylifedemo(312): onpause

08-31 08:53:33.796: info/activitylifedemo(312): onstop

5、在alllist中點選打開

08-31 08:54:14.286: info/activitylifedemo(312): onrestart

08-31 08:54:14.286: info/activitylifedemo(312): onstart

08-31 08:54:14.296: info/activitylifedemo(312): onresume

通過日志資訊,我們可以看到。activity的啟動過程:oncreate—onstart—onresume;下傳回鍵時:onpause—onstop—ondestroy 正如上面說是,當按下傳回鍵時,此activity彈出棧,程式銷毀。确實如此,我們再次 打開時的啟動過程又回到oncreate—onstart—onresume。ok,啟動之後按下home鍵,回到launcher,檢視列印資訊:onpause—onstop,再次打開的運作過程:onrestart—onstart—onresume。

我們通過對activity的各種操作,構成了activity的生命周期,我們看到無論對activity做如何的操作,都會接收到相關的回調方法,那麼我們在開發的過程中通過這些回調方法就可以寫工作,比如說釋放一些重量級的對象,網絡連接配接,資料庫連接配接,檔案讀等等。

以下是各個方法的詳細說明:

oncreate():當 activity 第一次建立時會被調用。在這個方法中你需要完成所有的正常靜态設定 ,比如建立一個視圖( view )、綁定清單的資料等等。如果能捕獲到 activity 狀态的話,這個方法傳遞進來的 bundle 對象将存放了 activity 目前的狀态。調用該方法後一般會調用 onstart() 方法。

onrestart():在 activity 被停止後重新啟動時會調用該方法。其後續會調用 onstart 方法。

onstart()à當 activity 對于使用者可見前即調用這個方法。如果 activity回到前台則接着調用 onresume() ,如果 activity 隐藏則調用onstop()

onresume():在 activity 開始與使用者互動前調用該方法。在這時該activity 處于 activity 棧的頂部,并且接受使用者的輸入。其後續會調用 onpause() 方法。

onpause():在系統準備開始恢複其它 activity 時會調用該方法。這個方法中通常用來送出一些還沒儲存的更改到持久資料 中,停止一些動畫或其它一些耗 cpu 的操作等等。無論在該方法裡面進行任何操作,都需要較快速完成,因為如果它不傳回的話,下一個 activity 将無法恢複出來。如果 activity 傳回到前台将會調用 onresume() ,如果 activity 變得對使用者不可見了将會調用onstop() 。

onstop():在 activity 對使用者不可見時将調用該方法。可能會因為目前 activity 正在被銷毀,或另一個 activity (已經存在的activity 或新的 activity )已經恢複了正準備覆寫它,而調用該方法。如果 activity 正準備傳回與使用者互動時後續會調用onrestart ,如果 activity 正在被釋放則會調用 ondestroy 。

ondestroy():在 activity 被銷毀前會調用該方法。這是 activity 能接收到的最後一個調用。可能會因為有人調用了 finish 方法使得目前activity 正在關閉,或系統為了保護記憶體臨時釋放這個 activity的執行個體,而調用該方法。你可以用 isfinishing 方法來區分這兩種不同的情況。

要啟動一個新的activity,我們可以通過調用context中的startactivity來啟動。像這樣:

<span style="font-size:18px;">intent intent = new intent(this, activitydemo.class);  

startactivity(intent);  // activitydemo是需要啟動的activity類  

通過上面的方法可以啟動新的activity了,但如果我要從目前的activity中傳遞資料到新的activity呢?很簡單:

<span style="font-size:18px;">intent intent = new intent(this,activitydemo.class);  

bundle bundle = new bundle();  

bundle.putboolean("bool_key", true);  

intent.putextras(bundle);  

startactivity(intent);  

還有,有時候我們需要啟動帶傳回值的activity,簡單的說就是需要新啟動的activity傳回時将值傳遞給啟動它的activity,像這樣:

<span style="font-size:18px;">intent intent = new intent(activitylifedemo.this,revalueactivity.class);  

startactivityforresult(intent, 0x1001);  

activitylifedemo是目前的activity,啟動revalueactivity,我們在activitylifedemo中需要擷取revalueactivity傳回來的值。那麼在revalueactivity中就必須這樣寫:

<span style="font-size:18px;">intent intent  = new intent();  

intent.putextra("revalue_key","haha-revalueactivity");  

setresult(0x1001, intent);</span>  

那麼“revalue_key”值在哪裡擷取呢?必須重寫onactivityresult方法,通過判斷requestcode,來确定

<span style="font-size:18px;">if(requestcode==0x1001){  

            string str = data.getstringextra("revalue_key");  

            log.i(tag, "傳回的值為:"+str);  

        }  

好了,詳細的請看代碼吧。下載下傳位址:http://download.csdn.net/detail/tangcheng_ok/3580700

通過重寫onsaveinstancestate()方法來實作activity的運作狀态,請注意以下幾點:

1)由于activity 對象被暫停或停止時,它仍然保留在記憶體裡面,關于它的成員資訊和目前狀态都是活動的,是以此時可以儲存activity的狀态,進而使使用者所作的activity的更改儲存在記憶體中

2)  當系統回收記憶體而将activity銷毀時,就無法儲存其狀态,是以需要調用onsaveinstancestate()方法來實作狀态的儲存

3)  很多情況并不需要保持狀态資訊,比如按下傳回鍵直接關閉程式,是以并不能保證會調用onsaveinstancestate。如果調用了該方法,一般是在onstop 方法之前且可能在 onpause 之後調用。盡管如此,即使你沒做任何操作或沒有實作 onsaveinstancestate() 方法,你的 activity 狀态也能通過activity 類裡面預設實作的 onsaveinstancestate 方法恢複出來。特别是會為布局中的視圖( view )預設調用onsaveinstancestate 方法,并在這個方法中允許每一個視圖提供它需要恢複的任何資訊。幾乎每一個 android架構中的 widget 都視情況實作了這個方法。

注:因為 onsaveinstancestate 方法不一定會被調用,是以你應該隻是用它來儲存一些 activity 的轉換過程狀态(即 ui 的狀态),而不能用來儲存永久性資料。但你可以用 onpause 方法在使用者離開 activity 時來儲存永久性資料,比如需要儲存到資料庫的資料。

有一個很好的方法可以用來檢驗應用程式儲存狀态的能力,就是簡單地旋轉你的裝置來改變螢幕的方向。因為當螢幕方向改變時,系統為了給新的方向提供一個可能合适的代替資源,會銷毀 activity 并建立一個新的。由于這個原因,你的 activity 是否能在其重新建立時完成儲存狀态就顯得尤為重要,因為使用者經常會在使用應用程式時旋轉螢幕的。

上文部分内容參考了:http://blog.csdn.net/sam_zhang1984/article/details/6430817,在這裡多謝這位部落客了。

通過上面的介紹,我們知道當點選back鍵時,程式調用了ondestroy方法,程式退出了,但是我們檢視其程序,發現調用了ondestroy方法之後這個activity還在運作。甚至調用了finish()方法之後程式還能在程序中看到。通過下面這種方式可以實作程式的完全退出:

<span style="font-size:18px;">intent intent = new intent();  

intent.setclass(context,mainactivity.class);  

intent.setflags(intent.flag_activity_clear_top);  

intent.putextra(“flag”,exit_application);  

context.startactivity(intnet);   

ok,到此為止。該準備下一篇了。