1、完整生命週期
上圖是Android Activity的生命週期圖,其中Resumed、Paused、Stopped狀態是靜態,這三個狀態下的Activity存在時間較長。
(1)Resumed:在此狀態時,使用者可以與Activity進行互動,Activity在最前端
(2)Paused:在此狀態時,Activity被另外一個Activity遮蓋,此Activity不可接受使用者輸入資訊。另外一個Activity來到最前面,半透明的,但並不會覆蓋整個螢幕。
(3)Stopped:在此狀態時,Activity完全被隱藏,不可見。保留當前資訊,Activity不執行任何代碼。
(4)Created與Started:系統調用onCreate()後迅速調用onStart(),然後迅速執行onResume()。
以上就是Android的Activity整個生命週期。
2、主Activity
使用者可以指定程式啟動的主介面,此時被聲明為“launcher或main”Activity的onCreate()方法被調用,成為程式的入口函數。該入口Activity可以在AndroidManifest.xml中定義主Activity。此時,主Activity必須使用以下標籤聲明:
複製代碼 代碼如下:
<activity android:name=".MainActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
3、一個新的Activity執行個體
系統首先調用新Activity的onCreate()方法,所以,我們必須實現onCreate()方法。如:聲明UI元素、定義成員變數、配置UI等。但是事情不宜太多,避免啟動程式太久而看不到介面。
複製代碼 代碼如下:
TextView mTextView; // Member variable for text view in the layout
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the user interface layout for this Activity
// The layout file is defined in the project res/layout/main_activity.xml
file
setContentView(R.layout.main_activity);
// Initialize member TextView so we can manipulate it later
mTextView = (TextView) findViewById(R.id.text_message);
// Make sure we're running on Honeycomb or higher to use ActionBar APIs
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// For the main activity, make sure the app icon in the action bar
// does not behave as a button
ActionBar actionBar = getActionBar();
actionBar.setHomeButtonEnabled(false);
}
}
onCreate()執行完即調用onStart()和onResume()方法,Activity不會在Created或者Started狀態停留。
4、銷毀Activity
Activity的最後一個回調是onDestroy(),系統會執行這個方法做為你的Activity要從系統中完全刪除的訊號。大多數APP不需實現此方法,因為局部類的references會隨著Activity的銷毀而銷毀。並且Activity應該在onPause()和onStop()方法中執行清楚Activity資源的操作。如果Activity在onCreate()時建立的後台線程,或者是其他有可能導致記憶體泄露的資源,你應該在onDestroy()時殺死它們。
複製代碼 代碼如下:
@Override
public void onDestroy() {
super.onDestroy(); // Always call the superclass
// Stop method tracing that the activity started during onCreate()
android.os.Debug.stopMethodTracing();
}
系統通常是在執行了onPause()與onStop()後在調用onDestroy(),除非在onCreate()中調用了finish()。例如,如果你的Activity只是做了一個臨時的邏輯跳轉功能,它使用用來決定跳轉到下一個Activity,這樣,你需要在onCreate()中調用finish()方法。系統就會直接調用onDestroy方法,其他生命週期就不會被執行。
5、暫停與恢複
當前Activity被其它可見組件阻塞,當前Activity部分可見,當前Activity進入Pause狀態。系統調用Activity中的onPause()方法,執行onResume()方法恢複。
當前Activity被其它組件完全阻塞,當前Activity完全不可見,則當前Activity進入Stop狀態。
當系統調用你的Activity中的onPause(),從技術上講,那意味著你的Activity仍然處於部分可見的狀態。通常在onPause()回調方法裡面做下面的事情。
(1)停止動畫或者其他正在啟動並執行操作,減少CPU浪費
(2)提交沒有儲存的改變,但僅僅是使用者離開時儲存的內容,如郵件
(3)釋放系統資源,如broadcast receivers、sensors、GPS或者其他任何影響電量的資源。
(4)如果程式正在使用Camera,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;
}
}
通常,不應該使用onPause()來儲存使用者改變的資料到永久儲存上,當你確認使用者期待那些改變能夠自動儲存的時候,才可以把那些資料存放區到永久儲存。然而,應該避免在onPause()時執行CPU-intensive的工作,例如寫資料到DB,因為他會導致切換Activity變得緩慢。這些工作應該放到onStop()中去坐。
如果,Activity實際上要被Stop,那麼應減少在onPause中的工作量,提高流暢性。
恢複Activity
使用者從Pause狀態恢複時,調用onResume()方法。此時Activity處於最前台,包括第一次建立時,此時,應該在onResume中初始化那些你在onPause方法裡釋放掉的組件,並執行那些Activity每次進入Resumed state都需要的初始化動作。
複製代碼 代碼如下:
@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
}
}
6、停止與重啟Activity
恰當的停止與重啟Activity會使使用者感知程式的進行。下面一些情境涉及停止與重啟:
(1)使用者開啟最近使用的App的菜單並切換到另外一個App,此時,你的App是被停止的,使用者回到你的App,那麼你的Activity被重啟。
(2)使用者在App中啟動一個新的Activity的操作,當前Activity會在新Activity建立後stop,如果使用者點擊back按鈕,回到上一個Activity,重啟
(3)使用者使用App,接到來電時。
停止狀態UI不可見。系統在Activity停止時會在記憶體中儲存了Activity執行個體,有時不需事先onStop(),onRestart()甚至onStart()方法,因為大多數的activity相對簡單,activity會自己停止與重啟。你只需要使用onPause來停止正在啟動並執行動作,並斷開系統資源連結。
上圖顯示:當使用者離開你的Activity,系統會調用onStop()來停止Activity,使用者返回時調用onRestart(),然後迅速調用onStart()與onResume(),無論什麼原因導致Activity停止,系統總會在onStop之前調用onPause
停止Activity
當你的Activity調用onStop方法,Activity不再可見,並且應該釋放那些不再需要的所有資源,一旦你的Activity停止了,系統會在不需要的這個activity時銷毀它的執行個體。在極端情況下,系統會直接殺死你的App進程,並且不執行Activity的onDestroy()回呼函數,因此你需要在onStop()來釋放資源,否則記憶體泄露。儘管onPause方法在onStop之前調用,應應該使用onStop來執行CPU-intensive的shut-down操作。如寫資料到DB。
當Activity停止,其對象會儲存在記憶體中,並且在Resume時重新調用,不需在恢複到Resumed state狀態前初始化那些被儲存在記憶體中得組件,系統為我們儲存了每一個在布局中的視圖的目前狀態。即使系統會在Activity stop時銷毀這個Activity,它仍然會儲存View對象的狀態到一個Bundle中,並且在使用者返回這個Activity時恢複他們。
重新建立Activity:當Activity在螢幕被旋轉時,會被destroy與recreated。此時會載入一些alternative的資源,如layout。預設情況下,系統使用Bundle執行個體來儲存每一個視圖對象中得資訊。為了使Android系統能夠恢複Activity中的View狀態,每個View都必須有一個唯一的ID
為了確保額外更多的資料到saved instance state,在Activity的聲明周期裡面存在一個添加的回呼函數,必須重寫onSaveInstanceState(),當使用者離開你的Activity時,系統會調用它。當系統調用這個函數時,系統會在你的Activity被一場Destroy時傳遞Bundle對象,這樣,你可以增加額外的資訊到Bundle中,並儲存在系統中。如果系統在Activity被Destroy之後想重新建立這個Activity執行個體時,之前的那個Bundle對象會被傳遞到Activity的onRestoreInstanceState()方法和onCreate()方法中。
儲存Activity狀態:當Activity開始Stop時,系統會調用onSaveInstanceState(),因此你的Activity可以用索引值對的集合來儲存狀態資訊,這個方法會預設儲存Activity視圖的狀態資訊,例如在EditText組件中得文本或者是ListView的滑動位置。為了給Activity儲存額外的狀態資訊,你必須實現onSaveInstanceState()並增加索引值對到Bundle中。如:
複製代碼 代碼如下:
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
恢複Activity狀態:當你的Activity從Destroy中重建,你可以從系統傳遞給你的Activity的Bundle中恢複儲存的狀態。onCreate()與onRestoreInstanceState()回調方法都接收到了同樣的Bundle,裡麵包含同樣的執行個體狀態資訊。因為onCreate()方法會在第一次建立新的Activity執行個體與重新建立之前被Destroy的執行個體時都被調用,你必須嘗試讀取Bundle對象之前檢查它是否為NULL,如果為NULL,系統第一次建立新Activity。否則是恢複被Destroy的Activity。
複製代碼 代碼如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// Probably initialize members with default values for a new instance
}
...
}
我們可以選擇實現onRestoreInstanceState(),而不是在onCreate方法裡恢複資料。onRestoreInstanceState()方法會在onStart()方法之後執行,系統僅僅會在存在需要恢複的狀態資訊時才會調用onRestoreInstanceState(),因此不需檢查Bundle是否為NULL。
複製代碼 代碼如下:
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}