1. 程式人生 > >Activity的生命週期及Intent(ActivityLifeCycle)

Activity的生命週期及Intent(ActivityLifeCycle)

 

1.Android生命週期

Android是使用任務棧(Task)來管理活動的,一個任務就是一組存放在棧裡的活動的集合,這個棧也被稱作返回棧(Back Stack)。棧是一種後進先出的資料結構*(後來者居上)。在預設情況下,每當我們啟動了一個新的活動,它會在返回棧中入棧,並處於棧頂的位置。而每當我們按下Back鍵或呼叫finish()方法去銷燬一個活動時,處於棧頂的活動就會出棧,這時前一個入棧的活動就會重新處於棧頂的位置。系統總是會顯示處於棧頂的活動給使用者。活動生命週期的四種狀態:

①執行狀態,當一個活動位於返回棧的棧頂時,這時活動就處於執行狀態。系統最不願意回收的就是處於執行狀態的活動,因為這會帶來非常差的使用者體驗。

②暫停狀態,當一個活動不再處於棧頂位置,但仍然可見時,這時活動就進入了暫停狀態,比如有一些活動以對話方塊的形式出現,只會佔用螢幕中間的部分位置,處於其下仍然可見的活動就是暫停狀態,系統也不願去回收這種狀態的活動(活動對於使用者仍然是可見的)。

③停止狀態:當一個活動不再處於棧頂位置,並且完全不可見的時候就進入了停止狀態,當有其他地方需要記憶體時,處於停止狀態的活動有可能會被系統回收。

④銷燬狀態:當一個活動從返回棧中移除後就變成銷燬狀態。系統會最傾向於回收這種狀態的活動,從而保證手機記憶體充足。

二、活動生命週期具體分析:Activity類中定義了7個回撥方法,覆蓋了活動生命週期的每隔環節。

①onCreate(),它會在活動第一次被建立的時候呼叫。開發者要在這個方法中完成活動的初始化操作,比如說載入佈局、繫結時間等。

②onStart(),這個方法在活動由不可見變為可見的時候呼叫。

③onResume(),這個方法在活動準備好和使用者進行互動的時候呼叫。此時的活動一定位於返回棧的棧頂,並且處於執行狀態。

④onPause(),這個方法在系統準備去啟動或者恢復另一個活動的時候呼叫。我們通常會在這個方法中將一些消耗CPU的資源釋放掉,以及儲存一些關鍵資料,但這個方法的執行速度一定要快,不然會影響到新的棧頂活動的使用。

⑤onStop(),這個方法在活動完全不可見的手呼叫。它和onPause方法的主要區別在於,如果啟動的新活動是一個對話方塊式的活動,那麼onPause()方法會的得到執行,而onStop()方法並不會執行。

⑥onDestroy(),這個方法在活動被銷燬之前呼叫,之後活動的狀態將變成銷燬狀態。

⑦onRestart(),這個方法在活動活動由停止狀態變為執行狀態時呼叫。

以上7個方法除了onRestart()方法之外,都是兩兩對應的,從而又將活動分為三個生存期。

①完整生存期。活動在onCreate方法和OnDestroy方法之間所經歷的,就是完整生存週期。一般情況下,一個活動會在onCreate方法中完成各種初始化操作,而在onDeatroy方法中完成釋放記憶體的操作。

②可見生存期。活動在onStart方法和onStop方法之間所經歷的,就是可見生存期。在可見生存期內,活動對於使用者總是可見的,即便有可能無法和使用者進行互動。我們可以通過這兩個方法,合理地管理那些對使用者的可見的資源。

③前臺生存期。活動在onResume方法和onPause方法之間所經歷的就是前臺生存期。在前臺生存期內,活動總是處於執行狀態,此時的活動是可以和使用者進行互動的,我們平時看到和接觸最多的也就是處於這個狀態下的活動。

 

小結:到這裡我們來個小結,當Activity啟動時,依次會呼叫onCreate(),onStart(),onResume(),而當Activity退居後臺時(不可見,點選Home或者被新的Activity完全覆蓋),onPause()和onStop()會依次被呼叫。當Activity重新回到前臺(從桌面回到原Activity或者被覆蓋後又回到原Activity)時,onRestart(),onStart(),onResume()會依次被呼叫。當Activity退出銷燬時(點選back鍵),onPause(),onStop(),onDestroy()會依次被呼叫,到此Activity的整個生命週期方法回撥完成。

2.Intent啟動Activity

 

要建立並顯示一個Activity,可以呼叫startActivity,並傳遞給它一個Intent,如下面的程式碼所示:

startActivity(Intent myIntent);

可以構造Intent來顯示地指定要開啟的Activity類,或者包含一個目標Activity必須執行的動作。在後一種情況中,執行時將會使用一個稱為“Intent解析(Intent resolution)”的過程來動態選擇Activity。

https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1541263682284&di=28df674e35a087744169a21d6dc2ca3c&imgtype=0&src=http%3A%2F%2Fwww.th7.cn%2Fd%2Ffile%2Fp%2F2014%2F08%2F10%2F6196647560a43ccdc28c517dfd77f9c6.png

 

 

3. 多個Activity之間共享資料

 

Activity之間共享資料有五種方式:

1.基於訊息的通訊機制 Intent ---boudle ,extra

資料型別有限,比如遇到不可序列化的資料Bitmap,InputStream, 或者LinkList連結串列等等資料型別就不太好用。

2. 利用static靜態資料,public static成員變數,也是可以是一個public類;

3.基於外部儲存的傳輸, File/Preference/ Sqlite ,如果要針對第三方應用需要Content Provider

4.基於IPC的通訊機制context 與Service之間的傳輸,如Activity與Service之間的通訊,定義AIDL介面檔案。

5. 基於Application Context

 

本程式是使用一個public類實現資料共

定義一個public類Status用來儲存活動狀態和顯示狀態在textview中,該public類定義了Map<String,String>型別的變數mMethodList儲存Activity Status , List<String>型別的變數mStatusMap儲存日誌資訊。

建構函式:

private Status() {
    mStatusMap = new LinkedHashMap<String, String>();
    mMethodList = new ArrayList<String>();
}

 

用一個getInstance()方法返回該類的一個物件(該物件封裝了上述兩個變數):

public static Status getInstance() {

    return ourInstance;
}

 

clear()函式用清除mMethodLis和mStatusMap儲存的活動狀態:

 

public void clear() {//清除日誌表和狀態表

        mMethodList.clear();

        mStatusMap.clear();

}

setStatus()函式用來將當前活動的資訊存進mMetodList和mStatusMap:

 

 

public void setStatus(String activityName, String status) {

        mMethodList.add(activityName + "." + status + "()");

        if (mStatusMap.containsKey(activityName)) mStatusMap.remove(activityName);

        mStatusMap.put(activityName, status);

}

getStatus()函式用來獲取活動狀態,並轉化為輸出格式:

    public String getStatus(String activityName) {

        String status = mStatusMap.get(activityName);

        status = status.substring(2, status.length());//把前面的on去掉

 

        // String manipulation to ensure the status value is spelled correctly.

        if (status.endsWith("e")) {

            status = status.substring(0, status.length() - 1);//以e結尾直接加d

        }

        if (status.endsWith("p")) {

            status = status + "p";//以p結尾雙寫p加ed

        }

        status = status + STATUS_SUFFIX;

        return status;

}

由於在當前Activity執行onResume()後,onStop()或onDestroy()才執行而且執行的時間很短,如果在執行onResume()的時候直接顯示到TextView會導致onStop或onDestroy()顯示不了,所以在顯示函式printStatus()中設定一個時間延遲,由圖可知時延大概在1.4s左右。該實驗將時延設定為2s。

 

 

public static void printStatus(final TextView viewMethods, final TextView viewStatus) {
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        public void run() {
            StringBuilder sbMethods = new StringBuilder();
            List<String> listMethods = mStatus.getMethodList();
            for (String method : listMethods) {
                  sbMethods.insert(0, method + "\r\n");
            }
            if(viewMethods != null) {
                viewMethods.setText(sbMethods.toString());
            }
            StringBuilder sbStatus = new StringBuilder();
            for (String key : mStatus.keySet()) {
                sbStatus.insert(0,key + ": " + mStatus.getStatus(key) + "\n");
            }
            if(viewStatus != null) {
                viewStatus.setText(sbStatus.toString());
            }
        }
    }, 2000);
}

然後在AActivity、BActivity、CActivity中定義Status物件,然後分別在onCreate(),onStart(),onResume(),onPause(),onDestroy()中呼叫相應函式

3.執行結果截圖

啟動程式初始化介面

緊接著點選START B按鈕後出現的介面

再點選START C按鈕後出現介面

然後點選FINISH C按鈕出現的介面

最後點選DIALOG出現的介面

 

 

原始碼:https://download.csdn.net/my