- Android開發與實戰
- 趙書蘭編著
- 4086字
- 2018-12-30 05:24:08
1.5 應用程序的生命周期
應用程序的生命周期是指進程在Android系統中從啟動到終止的所有階段,也就是Android程序啟動到停止的全過程。程序的生命周期由Android系統進行調試和控制。了解Android的生命周期是學習Android應用程序開發的基礎。
在Android系統中,當某個Activity調用startActivity(myIntent) 時,系統會在所有已經安裝的程序中尋找其intent filter和myIntent最匹配的一個Activity,啟動這個進程,并把這個intent通知給這個Activity。這就是一個程序的“生”。例如,在Home application中選擇“Web browser”,系統會根據這個intent找到并啟動Web browser程序,顯示Web browser的一個Activity用于瀏覽網頁(這個啟動過程有點類似在計算機上雙擊桌面上的一個圖標,啟動某個應用程序)。在Android中,所有的應用程序“生來就是平等的”,所以不光Android的核心程序甚至第三方程序也可以發出一個intent來啟動另外一個程序中的一個Activity。Android的這種設計非常有利于“程序部件”的重用。
1.5.1 進行優先級
一個Android程序的進程是何時被系統結束的呢?通俗地說,一個即將被系統關閉的程序是系統在內存不足(low memory)時,根據“重要性層次”選出來的“犧牲品”。一個進程的重要性是根據其中運行的部件和部件的狀態決定的。各種進程按照重要性從高到低排列,如圖1-32所示。

圖1-32 Android進程優先級效果圖
1.前臺進程
前臺進程是與用戶正在交互的進程,也是Android系統中最重要的進程。處于前臺進程一般包含以下四種情況。
● 進行中的Activity正在與用戶進行交互。
● 進程服務被Activity調用,而且這個Activity正在與用戶進行交互。
● 進程服務正在執行生命周期中的回調函數,如onCreate()、onStart()或onDestroy()。
● 進程的BroadcastReceiver正在執行onReceive()函數。
Android系統為多任務操作系統,當系統中的多個前臺進程同時運行時,如果出現資源不足的情況,此時Android內核將自動清除部分前臺進程,保證最主要的用戶界面能夠及時響應操作。
2.可見進程
可見進程是指在屏幕上顯示,但不在前臺的程序。例如,一個前臺進程以對話框的形式顯示在該進程前面。這樣的進程也很重要,它們只有在系統沒有足夠內存運行所有前臺進程時,才會被結束。
3.服務進程
服務進程在后臺持續運行,如后臺音樂播放、后臺數據上傳/下載等。這樣的進程對用戶來說一般很有用,所以只有當系統沒有足夠內存來維持所有的前臺進程和可見進程時,才會被結束。
4.后臺進程
后臺進程程序擁有一個用戶不可見的Activity。這樣的程序在系統內存不足時,按照LRU的順序被結束。
5.空進程
空進程不包含任何活動的程序部件,系統可能隨時關閉這類進程。
從某種意義上講,垃圾收集機制把程序員從“內存管理噩夢”中解放出來,而Android的進程生命周期管理機制把用戶從“任務管理噩夢”中解放出來。筆者見過一些Nokia S60用戶和Windows Mobile用戶,要么因為長期不關閉多余的應用程序而導致系統變慢,要么因為不時查看應用程序列表而影響使用體驗。Android使用Java作為應用程序API,并且結合其獨特的生命周期管理機制,同時為開發者和使用者提供最大程度的便利。
1.5.2 Activity的生命周期
Activity的生命周期是指應用程序的Activity從啟動到銷毀的全過程。Activity的生命周期是在Android應用程序設計中最重要的內容,直接關系到用戶程序的界面和功能。
1.活動棧
每一個活動的狀態是由它在活動棧中所處的位置所決定的,活動棧是當前所有正在運行的進程的后進先出的集合。當一個新的活動啟動時,當前的前臺屏幕就會移動到棧頂。如果用戶使用Back(返回)按鈕返回到了剛才的活動,或者前臺活動被關閉了,那么棧中的下一個活動就會移動到棧頂,變為活動狀態。圖1-33說明了這個過程。

圖1-33 活動棧流程圖
2.Activity的狀態
隨著活動的創建和銷毀,它們會按照圖1-33所示的那樣,從棧中移進移出。在這個過程中,它們也經歷了活動、暫停、停止和非活動4種可能的狀態,如圖1-34所示。

圖1-34 Activity的狀態
(1)活動狀態:當一個活動位于棧頂的時候,它是可見的、被關注的前臺活動,這時它可以接收用戶輸入。Android將會不惜一切代價來保持它處于活動狀態,并根據需要來銷毀棧下面部分的活動,以保證這個活動擁有它所需要的資源。當另一個活動變為活動狀態時,這個活動就將被暫停。
(2)暫停狀態:在某些情況下,活動是可見的,但是沒有被關注,此時它就處于暫停狀態。當一個透明的或者非全屏的活動位于某個處于活動狀態的活動之前時,這個透明的或者非全屏的活動就會達到這個狀態。當活動被暫停的時候,它仍然會被當做近似于活動狀態的狀態,但是它不能接收用戶的輸入事件。在極端情況下,當一個活動變得完全不可見的時候,它就會變為停止狀態。
(3)停止狀態:當一個活動不可見的時候,它就處于停止狀態。此時,活動仍然會停留在內存中,保存所有的狀態和成員信息,然而當系統的其他地方要求使用內存的時候,它們就會成為被清除的首要候選對象。在一個活動停止的時候,保存數據和當前的UI狀態是很重要的。一旦一個活動被退出或者關閉,它就會變為非活動狀態。
(4)非活動狀態:當一個活動被銷毀之后,在它啟動之前就處于非活動狀態。處于非活動狀態的活動已經從活動棧中移除了,因此,在它們可以被顯示和使用之前,需要被重新啟動。
在Android系統中,采用“棧”結構來管理Activity,這是一種“后進先出”的原則,如圖1-35所示。當一個Activity被啟用時,將執行入棧操作。位于棧頂的Activity處于活動狀態,其他Activity則處于暫停狀態或者停止狀態。當Activity關閉時,將執行出棧操作,從而變成非活動狀態。當Android系統資源緊張時,Android內核也會終止部分長久沒有響應的Activity,使之為非活動狀態,從而釋放系統資源。

圖1-35 Activity的棧結構
3.管理Activity的生命周期
在Activity系統中,一般通過Activity的事件回調函數來管理Activity的生命周期。這些事件回調函數如下:
public class MyActivity extends Activity { void onCreate(Bundle savedInstanceState); void onStart(); void onRestart(); void onResume(); void onPause(); void onStop(); void onDestroy(); }
這些Activity生命周期的事件回調函數將會被Android系統自動調用。用戶也可以重載這些事件回調函數來完成自己的操作。Activity生命周期的事件回調函數的說明如表1-3所示。
表1-3 Activity生命周期的事件回調函數

在Android系統中,Activity的生命周期,以及各個事件回調函數之間的跳轉,如圖1-36所示。

圖1-36 Activity的生命周期
另外,當由于系統資源緊張時,Activity可能會被終止。此時,Android提供了相應的狀態保存/恢復的事件回調函數,如表1-4所示。
表1-4 Activity狀態保存/恢復的事件回調函數

1.5.3 Activity生命周期調用順序
一般來說,Activity的生命周期可分為全生命周期、可視生命周期和活動生命周期三類。每種生命周期中包含不同的事件回調函數,各個事件回調函數的調用順序也不同,如圖1-37所示。

圖1-37 Activity生命周期的調用順序圖
對于Activity全生命周期,事件回調函數的調用順序為onCreate()→onStart()→onResume()→onPause()→onStop()→onDestroy()。每一步調用的含義如下:
● 調用onCreate()函數分配資源。
● 調用onStart()將Activity顯示在屏幕上。
● 調用onResume()獲取屏幕焦點。
● 調用onPause()、onStop和onDestroy(),釋放資源并銷毀進程。
對于Activity可視生命周期,事件回調函數的調用順序為onSaveInstanceState()→onPause()→onStop()→onRestart()→onStart()→onResume()。每一步調用的含義如下:
● 調用onSaveInstanceState()函數保存Activity狀態。
● 調用onPause()和onStop(),停止對不可見Activity的更新。
● 調用onRestart()恢復界面上需要更新的信息。
● 調用onStart()和onResume()重新顯示Activity,并接受用戶交互。
對于活動生命周期,事件回調函數的調用順序為onSaveInstanceState()→onPause()→onResume()。每一步調用的含義如下:
● 調用onSaveInstanceState()保存Activity的狀態。
● 調用onPause()停止與用戶交互。
● 調用onResume()恢復與用戶的交互。
1.5.4 Service的生命周期
Service生命周期一般有兩種使用方式。
Service可以被啟動或者允許被啟動直到有人停止了它或者它自己停止了。在這種模式下,它通過Context.startService()方法開始,通過Context.stopService()方法停止。它可以通過Service.stopSelf()方法或者Service.stopSelfResult()方法來停止自己。只要調用一次stopService()方法便可以停止服務,無論調用了多少次的啟動服務方法。
Service可以通過定義好的接口來編程,客戶端建立一個與Service的鏈接,并使用此鏈接與Service進行通話。通過Context.bindService()方法來綁定服務,通過Context.unbindService()方法來關閉服務。多個客戶端可以綁定同一個服務。如果Service還未被啟動,bindService()方法可以啟動服務。
這兩種模式是完全獨立的。你可以綁定一個已經通過startService()方法啟動的服務。例如,一個后臺播放音樂服務可以通過startService()和一個intend對象來播放音樂。可能用戶在播放過程中要執行一些操作,例如,獲取歌曲的一些信息,此時Activity可以通過調用bindServices()方法與Service建立連接。這種情況下,stopServices()方法實際上不會停止服務,直到最后一次綁定關閉。
像一個Activity那樣,Service服務也有生命周期,也提供了事件回調函數:void onCreate()、void onStart(Intent intent)、void onDestroy()。
通過實現這三個生命周期方法,可以監聽Service的兩個嵌套循環的生命周期。
1.Service整個生命周期
Service整個生命周期是在onCreate()和onDestroy()方法之間。和Activity一樣,在onCreate()方法里初始化,在onDestroy()方法里釋放資源。例如,一個背景音樂播放服務可以在onCreate()方法里播放,在onDestroy()方法里停止。
2.Service活動生命周期
Service活動生命周期是在onStart()之后,這個方法會處理通過startServices()方法傳遞來的intent對象。音樂Service可以通過intent對象來找到要播放的音樂,然后開始后臺播放。
Service停止時沒有相應的回調方法,即沒有onStop()方法。onCreate()方法和onDestroy()方法針對的是所有的Service,無論它們是否啟動。然而,只有通過startService()方法啟動的Service才會被調用onStart()方法。如果一個Service允許其他命令綁定,那么需要實現以下額外的方法:
IBinder onBind(Intent intent) boolean onUnbind(Intent intent) void onRebind(Intent intent)
onBind()回調方法會繼續傳遞通過bindService()傳遞來的intent對象。onUnbind()會處理傳遞給unbindService()的intent對象。如果Service允許綁定,onBind()會返回客戶端與服務互相聯系的通信頻道。如果建立了一個新的客戶端與服務的鏈接,onUnbind()方法可以請求調用onRebind()方法。
1.5.5 Android生命周期綜合實例
下面通過用Java代碼來完成Android生命周期,其完整代碼如下:
import android.app.Activity; import android.os.Bundle; public class MyActivity extends Activity { // 在完整生存期開始的時候調用 @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); // 初始化一個活動 } // 在onCreate方法完成之后調用,用來恢復UI狀態 @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); //從savedInstanceState中恢復UI狀態 // 這個bundle也被傳遞給onCreate } // 在一個活動進程的后續的可見生存期之前調用 @Override public void onRestart() { super.onRestart(); // 當知道這個進程中的活動已經可見之后,載入改變 } // 在可見生存期開始時調用 @Override public void onStart() { super.onStart(); // 既然活動可見,就應用任何要求的UI改變 } // 在活動狀態生存期開始時調用 @Override public void onResume() { super.onResume(); //恢復活動所需要的任何暫停的UI更新、線程或者進程,但是當不活動 //的時候,就掛起它們 } // 在活動狀態生存期結束的時候調用,用來保存UI狀態改變 @Override public void onSaveInstanceState(Bundle savedInstanceState) { //把UI狀態改變保存到savedInstanceState //如果進程被銷毀或者重啟,那么這個bundle將被傳遞給 //onCreate super.onSaveInstanceState(savedInstanceState) } // 在活動狀態生存期結束時調用 @Override public void onPause() { //當活動不是前臺的活動狀態的活動時,掛起不需要更新的UI更新、 //線程或者CPU密集的進程 super.onPause(); } // 在可見生存期結束時調用 @Override public void onStop() { // 當進程不可見的時候,掛起不需要的剩下的UI更新、線程或者處理, // 保存所有的編輯或者狀態改變,因為這個進程可能會被銷毀(從而為 // 其他進程釋放資源) super.onStop(); } // 在完整生存期結束時調用 @Override public void onDestroy() { // 清空所有的資源,包括結束線程、關閉數據庫鏈接等 super.onDestroy(); } }