1. 程式人生 > >Activity生命週期總結

Activity生命週期總結

Activity 是一個應用元件,使用者可與其提供的螢幕進行互動,以執行撥打電話、拍攝照片、傳送電子郵件或檢視地圖等操作。每個 Activity 都會獲得一個用於繪製其使用者介面的視窗。視窗通常會充滿螢幕,但也可小於螢幕並浮動在其他視窗之上。

一個應用通常由多個彼此鬆散聯絡的 Activity 組成。一般會指定應用中的某個 Activity 為“主” Activity,即首次啟動應用時呈現給使用者的那個 Activity。而且每個 Activity 均可啟動另一個 Activity,以便執行不同的操作。每次新 Activity 啟動時,前一 Activity 便會停止,但系統會在堆疊(“返回棧”)中保留該 Activity。當新 Activity 啟動時,系統會將其推送到返回棧上,並取得使用者焦點。返回棧遵循“後進先出”堆疊機制,因此,當用戶完成當前 Activity 並按“返回”按鈕時,系統會從堆疊中將其彈出(並銷燬),然後恢復前一 個Activity。

當一個 Activity 因某個新 Activity 啟動而停止時,系統會通過該 Activity 的生命週期回撥方法通知其這一狀態變化。Activity 因狀態變化—系統是建立 Activity、停止 Activity、恢復 Activity 還是銷燬 Activity—而收到的回撥方法可能有若干種,每一種回撥方法都會提供執行與該狀態變化相應的特定操作的機會。例如,停止時,Activity 應釋放任何大型物件,例如網路或資料庫連線。當 Activity 恢復時,可以重新獲取所需資源,並恢復執行中斷的操作。這些狀態轉變都是 Activity 生命週期的一部分。

下圖為Activity生命週期圖。

根據Activity的複雜程度,可能不需要實現所有生命週期方法。但是,瞭解每個方法並實現確保您的應用按照使用者期望的方式執行的方法非常重要。正確實現您的Activity生命週期方法可確保您的應用按照以下幾種方式良好執行,包括:

1、如果使用者在使用您的應用時接聽來電或切換到另一個應用,它不會崩潰。

2、在使用者未主動使用它時不會消耗寶貴的系統資源。

3、如果使用者離開您的應用並稍後返回,不會丟失使用者的進度。

4、當螢幕在橫向和縱向之間旋轉時,不會崩潰或丟失使用者的進度。


主要存在以下幾個過程:

1、啟動Activity:執行順序為:onCreate->onStart->onResume

2、結束Activity:執行順序為:onPause->onStop->onDestoty,但是有一點需要注意:當在onCreate裡面呼叫finish的時候,會直接呼叫onDestory。

3、鎖屏:執行順序為:onPause

4、解鎖:執行順序為:onResume

5、彈出半透明對話方塊:執行順序為:onPause

6、結束半透明對話方塊:執行順序為:onResume

7、跳轉到別的Activity:假設本activity為A,跳轉的activity為B,則執行順序為:A:onPause -> B:onCreate->onStart->onResume->A:onStop,也就說ActivityA先onPause,當啟動完B後再onStop,這就是為什麼不能在onPause裡面執行耗時操作的原因,因為耗時的操作會阻礙Activity的跳轉,耗時的操作應該在onStop中完成。當然,如果必須在第一個 Activity 停止時向資料庫寫入資料,以便下一個 Activity 能夠讀取該資料,那麼操作就必須在onPause裡面完成。

8、從別的Activity返回:假設從上面的activityB返回到activityA,則執行順序為:B:onPause->A:onRestart->onStart->onResume->B:onStop->onDestory。

總而言之,主要分為兩部分:

(1)、當activity部分可見的時候,只會onPause而不會繼續執行onStop,然後恢復的時候相對應執行onResume。

一般此時在onPause執行下述操作:

1、停止動畫或其他可能消耗CPU的操作

2、提交未儲存的更改

3、釋放系統資源,比如廣播接收器、感測器手柄(比如 GPS) 或當您的Activity暫停且使用者不需要它們時仍然可能影響電池壽命的任何其他資源,比如如果你使用攝像頭,那麼onPause是釋放它的好位置,如下所示:

@Override
public void onPause() {
    super.onPause();  // Always call the superclass method first

    // Release the Camera because we don't need it when paused
    // and other activities might need to use it.
    if (mCamera != null) {
        mCamera.release()
        mCamera = null;
    }
}

當用戶從“暫停”狀態繼續您的Activity時,系統會呼叫 onResume() 方法。每當Activity進入前臺時系統便會呼叫此方法,包括它初次建立之時。 同樣地,應該實現onResume() 初始化在 onPause() 期間釋放的元件並且執行每當Activity進入“繼續”狀態時必須進行的任何其他初始化操作(比如開始動畫和初始化只在Activity具有使用者焦點時使用的元件),比如執行攝像頭的初始化操作:

@Override
public void onResume() {
    super.onResume();  // Always call the superclass method first

    // Get the Camera instance as the activity achieves full user focus
    if (mCamera == null) {
        initializeCamera(); // Local method to handle camera init
    }
}

(2)、當activity完全不可見的時候,會執行:onPause->onStop,然後恢復的時候相對應執行:onRestart->onStart->onResume,只是需要注意當前Activity和即將要跳轉的Activity的生命週期的執行順序。

當Activity收到onStop回撥時,它不再可見,此時應該釋放幾乎所有使用者不使用時不需要的資源,應該在onStop中執行更大、佔用更多CPU資源的關閉操作,比如向資料庫寫入資訊。

重新建立Activity

當Activity因使用者按了返回 或Activity自行完成而被銷燬時,系統的 Activity 例項概念將永久消失,因為行為指示不再需要Activity。 但是,如果系統因系統侷限性(而非正常應用行為)而銷燬Activity,儘管 Activity 實際例項已不在,系統會記住其存在,這樣,如果使用者導航回例項,系統會使用描述Activity被銷燬時狀態的一組已儲存資料建立Activity的新例項。 系統用於恢復先前狀態的已儲存資料被稱為“例項狀態”,並且是 Bundle 物件中儲存的鍵值對集合。

注意:每次使用者旋轉螢幕時,Activity將被銷燬並重新建立。 當螢幕方向變化時,系統會銷燬並重新建立前Activity,因為螢幕配置已更改並且Activity可能需要載入備用資源(比如佈局)。

當系統由於某種原因意外銷燬Activity的時候,系統會先呼叫 onSaveInstanceState()。系統會向該方法傳遞一個 Bundle,你可以在其中使用 putString() 和 putInt() 等方法以名稱-值對形式儲存有關 Activity 狀態的資訊。然後,如果系統終止你的應用程序,並且使用者返回您的 Activity,則系統會重建該 Activity,並將 Bundle 同時傳遞給 onCreate() 和 onRestoreInstanceState()。你可以使用上述任一方法從 Bundle 提取您儲存的狀態並恢復該 Activity 狀態。如果沒有狀態資訊需要恢復,則傳遞給你的 Bundle 是空值(如果是首次建立該 Activity,就會出現這種情況),具體過程如下圖所示:

無法保證系統會在銷燬你的 Activity 前呼叫 onSaveInstanceState(),因為存在不需要儲存狀態的情況(例如使用者使用“返回” 按鈕離開你的 Activity 時,因為使用者的行為是在顯式關閉 Activity)。 如果系統呼叫onSaveInstanceState(),它會在呼叫 onStop() 之前,並且可能會在呼叫 onPause() 之前進行呼叫。

不過,即使你什麼都不做,也不實現 onSaveInstanceState(),Activity 類的 onSaveInstanceState() 預設實現也會恢復部分 Activity 狀態。具體地講,預設實現會為佈局中的每個 View 呼叫相應的 onSaveInstanceState() 方法,讓每個檢視都能提供有關自身的應儲存資訊。Android 框架中幾乎每個小工具都會根據需要實現此方法,以便在重建 Activity 時自動儲存和恢復對 UI 所做的任何可見更改。例如,EditText 小工具儲存使用者輸入的任何文字,CheckBox 小工具儲存複選框的選中或未選中狀態。你只需為想要儲存其狀態的每個小工具提供一個唯一的 ID(通過 android:id 屬性)。如果小工具沒有 ID,則系統無法儲存其狀態。

具體程式碼就不貼了,只是記錄一下方便日後查閱,有不足之處,還請指出。

參考加翻譯: