編寫:kesenhoo - 原文:http://developer.android.com/training/basics/activity-lifecycle/starting.html
不同于其他編程范式(程序從main()
方法開始啟動(dòng)),Android系統(tǒng)根據(jù)生命周期的不同階段喚起對(duì)應(yīng)的回調(diào)函數(shù)來(lái)執(zhí)行代碼。系統(tǒng)存在啟動(dòng)與銷毀一個(gè)activity的一套有序的回調(diào)函數(shù)。
本課介紹生命周期中最重要的回調(diào)函數(shù),并演示如何處理啟動(dòng)一個(gè)activity所涉及到的回調(diào)函數(shù)。
在一個(gè)activity的生命周期中,系統(tǒng)會(huì)像金字塔模型一樣去調(diào)用一系列的生命周期回調(diào)函數(shù)。Activity生命周期的每一個(gè)階段就像金字塔中的臺(tái)階。當(dāng)系統(tǒng)創(chuàng)建了一個(gè)新的activity實(shí)例,每一個(gè)回調(diào)函數(shù)會(huì)向上一階移動(dòng)activity狀態(tài)。處在金字塔頂端意味著當(dāng)前activity處在前臺(tái)并處于用戶可與其進(jìn)行交互的狀態(tài)。
當(dāng)用戶退出這個(gè)activity時(shí),為了回收該activity,系統(tǒng)會(huì)調(diào)用其它方法來(lái)向下一階移動(dòng)activity狀態(tài)。在某些情況下,activity會(huì)隱藏在金字塔下等待(例如當(dāng)用戶切換到其他app),此時(shí)activity可以重新回到頂端(如果用戶回到這個(gè)activity)并恢復(fù)用戶離開時(shí)的狀態(tài)。
http://wiki.jikexueyuan.com/project/android-training-geek/images/basic-lifecycle.png" alt="basic-lifecycle" />
Figure 1. 下面這張圖講解了activity的生命周期:(這個(gè)金字塔模型要比之前Dev Guide里面的生命周期圖更加容易理解,更加形象)
根據(jù)activity的復(fù)雜度,也許不需要實(shí)現(xiàn)所有的生命周期方法。但了解每一個(gè)方法的回調(diào)時(shí)機(jī)并在其中填充相應(yīng)功能,使得確保app能夠像用戶期望的那樣執(zhí)行是很有必要的。如何實(shí)現(xiàn)一個(gè)符合用戶期待的app,我們需要注意下面幾點(diǎn):
下面的課程會(huì)介紹上圖所示的幾個(gè)生命狀態(tài)。然而,其中只有三個(gè)狀態(tài)是靜態(tài)的,這三個(gè)狀態(tài)下activity可以存在一段比較長(zhǎng)的時(shí)間。(其它幾個(gè)狀態(tài)會(huì)很快就切換掉,停留的時(shí)間比較短暫)
其它狀態(tài) (Created與Started)都是短暫的,系統(tǒng)快速的執(zhí)行那些回調(diào)函數(shù)并通過(guò)執(zhí)行下一階段的回調(diào)函數(shù)移動(dòng)到下一個(gè)狀態(tài)。也就是說(shuō),在系統(tǒng)調(diào)用onCreate(), 之后會(huì)迅速調(diào)用onStart(), 之后再迅速執(zhí)行onResume()。以上就是基本的activity生命周期。
當(dāng)用戶從主界面點(diǎn)擊程序圖標(biāo)時(shí),系統(tǒng)會(huì)調(diào)用app中被聲明為"launcher" (or "main") activity中的onCreate()方法。這個(gè)Activity被用來(lái)當(dāng)作程序的主要進(jìn)入點(diǎn)。
我們可以在AndroidManifest.xml中定義作為主activity的activity。
這個(gè)main activity必須在manifest使用包括 MAIN
action 與 LAUNCHER
category 的<intent-filter>
標(biāo)簽來(lái)聲明。例如:
<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>
Note:當(dāng)你使用Android SDK工具來(lái)創(chuàng)建Android工程時(shí),工程中就包含了一個(gè)默認(rèn)的聲明有這個(gè)filter的activity類。
如果程序中沒(méi)有聲明了MAIN action 或者LAUNCHER category的activity,那么在設(shè)備的主界面列表里面不會(huì)呈現(xiàn)app圖標(biāo)。
大多數(shù)app包括多個(gè)activity,使用戶可以執(zhí)行不同的動(dòng)作。不論這個(gè)activity是當(dāng)用戶點(diǎn)擊應(yīng)用圖標(biāo)創(chuàng)建的main activtiy還是為了響應(yīng)用戶行為而創(chuàng)建的其他activity,系統(tǒng)都會(huì)調(diào)用新activity實(shí)例中的onCreate()方法。
我們必須實(shí)現(xiàn)onCreate()方法來(lái)執(zhí)行程序啟動(dòng)所需要的基本邏輯。例如可以在onCreate()方法中定義UI以及實(shí)例化類成員變量。
例如:下面的onCreate()方法演示了為了建立一個(gè)activity所需要的一些基礎(chǔ)操作。如聲明UI元素,定義成員變量,配置UI等。(onCreate里面盡量少做事情,避免程序啟動(dòng)太久都看不到界面)
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);
}
}
Caution:用SDK_INT來(lái)避免舊的系統(tǒng)調(diào)用了只在Android 2.0(API level 5)或者更新的系統(tǒng)可用的方法(上述if條件中的代碼)。舊的系統(tǒng)調(diào)用了這些方法會(huì)拋出一個(gè)運(yùn)行時(shí)異常。
一旦onCreate 操作完成,系統(tǒng)會(huì)迅速調(diào)用onStart() 與onResume()方法。我們的activity不會(huì)在Created或者Started狀態(tài)停留。技術(shù)上來(lái)說(shuō), activity在onStart()被調(diào)用后開始被用戶可見(jiàn),但是 onResume()會(huì)迅速被執(zhí)行使得activity停留在Resumed狀態(tài),直到一些因素發(fā)生變化才會(huì)改變這個(gè)狀態(tài)。例如接收到一個(gè)來(lái)電,用戶切換到另外一個(gè)activity,或者是設(shè)備屏幕關(guān)閉。
在后面的課程中,我們將看到其他方法是如何使用的,onStart() 與 onResume()在用戶從Paused或Stopped狀態(tài)中恢復(fù)的時(shí)候非常有用。
Note: onCreate() 方法包含了一個(gè)參數(shù)叫做savedInstanceState,這將會(huì)在后面的課程 - 重新創(chuàng)建activity涉及到。
http://wiki.jikexueyuan.com/project/android-training-geek/images/basic-lifecycle-create.png" alt="basic_lifecycle-create" />
Figure 2. 上圖顯示了onCreate(), onStart() 和 onResume()是如何執(zhí)行的。當(dāng)這三個(gè)順序執(zhí)行的回調(diào)函數(shù)完成后,activity會(huì)到達(dá)Resumed狀態(tài)。
activity的第一個(gè)生命周期回調(diào)函數(shù)是 onCreate(),它最后一個(gè)回調(diào)是onDestroy().當(dāng)收到需要將該activity徹底移除的信號(hào)時(shí),系統(tǒng)會(huì)調(diào)用這個(gè)方法。
大多數(shù) app并不需要實(shí)現(xiàn)這個(gè)方法,因?yàn)榫植款惖膔eferences會(huì)隨著activity的銷毀而銷毀,并且我們的activity應(yīng)該在onPause()與onStop()中執(zhí)行清除activity資源的操作。然而,如果activity含有在onCreate調(diào)用時(shí)創(chuàng)建的后臺(tái)線程,或者是其他有可能導(dǎo)致內(nèi)存泄漏的資源,則應(yīng)該在OnDestroy()時(shí)進(jìn)行資源清理,殺死后臺(tái)線程。
@Override
public void onDestroy() {
super.onDestroy(); // Always call the superclass
// Stop method tracing that the activity started during onCreate()
android.os.Debug.stopMethodTracing();
}
Note: 除非程序在onCreate()方法里面就調(diào)用了finish()方法,系統(tǒng)通常是在執(zhí)行了onPause()與onStop() 之后再調(diào)用onDestroy() 。在某些情況下,例如我們的activity只是做了一個(gè)臨時(shí)的邏輯跳轉(zhuǎn)的功能,它只是用來(lái)決定跳轉(zhuǎn)到哪一個(gè)activity,這樣的話,需要在onCreate里面調(diào)用finish方法,這樣系統(tǒng)會(huì)直接調(diào)用onDestory,跳過(guò)生命周期中的其他方法。