當一個應用的組件開始運行,並且這個應用沒有其它的組件在運行,系統會為這個應用啟動一個新的Linux進程,這個進程只有一個線程.默認情況下,一個應用的所有組件都運行在一個進程和線程(主線程)中.如果一個應用的線程開始運行,並且已經存在這個應用的線程了(因為有這個應用程序的另一個組件已經運行了),於是這個組件就會在這個已有的進程中啟動並且運行在同一個線程中.然而,你完全可以安排不同的組件運行於不同的進程,並且你可以為任何程序創建另外的線程.
默認下,同一個程序的所有組件都運行在同一個進程中並且大多數程序不必改變這一狀況.然而,如果你非要與眾不同,也可以通過修改manifest文件實現.
manifest文件中的所有支持Android:process屬性的那些項(<activity>,<service>, <receiver>, 和<provider>)都可以指定一個進程,於是這些組件就會在這個進程中運行.你可以設置這個屬性使每個組件運行於其自己的進程或只是其中一些組件共享一個進程.你也可以設置android:process以使不同應用的組件們可以運行於同一個進程—假如這些應用共享同一個用戶ID並且有相同的數字證書.
<application>元素也支持android:process屬性,用於為所有的組件指定一個默認值.
Android可能在某些時刻決定關閉一個進程,比如內存很少了並且另一個進程更迫切的需要啟動時.進程被關閉時,其中的組件們都被銷毀.如果重新需要這些組件工作時,進程又會被創建出來.
當決定關閉哪些線程時,Android系統會衡量進程們與用戶的緊密程度.例如,比起一個具有可見的activity的進程,那些所含activity全部不可見的進程更容易被關閉.如何決定一個進程是否被關閉,取決於進程中運行的組件們的狀態.決定關閉進程的規則將在下面討論.
Android系統會盡量維持一個進程的生命,直到最終需要為新的更重要的進程騰出內存空間。為了決定哪個該殺哪個該留,系統會跟據運行於進程內的組件的和組件的狀態把進程置於不同的重要性等級。當需要系統資源時,重要性等級越低的先被淘汰。
重要性等級被分為5個檔。下面列出了不同類型的進程的重要性等級(第一個進程類型是最重要的,也是最後才會被殺的):
用戶當前正在做的事情需要這個進程。如果滿足下面的條件,一個進程就被認為是前台進程:
這個進程擁有一個正在與用戶交互的Activity(這個Activity的onResume() 方法被調用)。
這個進程擁有一個綁定到正在與用戶交互的activity上的Service。
這個進程擁有一個前台運行的Service — service調用了方法 startForeground().
這個進程擁有一個正在執行其任何一個生命周期回調方法(onCreate(),onStart(), 或onDestroy())的Service。
這個進程擁有正在執行其onReceive()方法的BroadcastReceiver。
通常,在任何時間點,只有很少的前台進程存在。它們只有在達到無法調合的矛盾時才會被殺--如果內存太小而不能繼續運行時。通常,到了這時,設備就達到了一個內存分頁調度狀態,所以需要殺一些前台進程來保證用戶界面的反應
一個進程不擁有運行於前台的組件,但是依然能影響用戶所見。滿足下列條件時,進程即為可見:
這個進程擁有一個不在前台但仍可見的Activity(它的onPause()方法被調用)。當一個前台activity啟動一個對話框時,就出了這種情況。
一個可見進程被認為是極其重要的。並且,除非只有殺掉它才可以保證所有前台進程的運行,否則是不能動它的。
這個進程擁有一個綁定到可見activity的Service。
一個進程不在上述兩種之內,但它運行著一個被startService()所啟動的service。
盡管一個服務進程不直接影響用戶所見,但是它們通常做一些用戶關心的事情(比如播放音樂或下載數據),所以系統不到前台進程和可見進程活不下去時不會殺它。一個進程擁有一個當前不可見的activity(activity的onStop()方法被調用)。
這樣的進程們不會直接影響到用戶體驗,所以系統可以在任意時刻殺了它們從而為前台、可見、以及服務進程們提供存儲空間。通常有很多後台進程在運行。它們被保存在一個LRU(最近最少使用)列表中來確保擁有最近剛被看到的activity的進程最後被殺。如果一個activity正確的實現了它的生命周期方法,並保存了它的當前狀態,那麼殺死它的進程將不會對用戶的可視化體驗造成影響。因為當用戶返回到這個activity時,這個activity會恢復它所有的可見狀態。
一個進程不擁有入何active組件。
保留這類進程的唯一理由是高速緩存,這樣可以提高下一次一個組件要運行它時的啟動速度。系統經常為了平衡在進程高速緩存和底層的內核高速緩存之間的整體系統資源而殺死它們。
跟據進程中當前活動的組件的重要性,Android會把進程按排在其可能的最高級別。例如,如果一個進程擁有一個service和一個可見的activity,進程會被定為可見進程,而不是服務進程。
另外,如果被其它進程所依賴,一個進程的級別可能會被提高—一個服務於其它進程的進程,其級別不可能比被服務進程低。
因為擁有一個service的進程比擁有一個後台activitie的進程級別高,所以當一個activity啟動一個需長時間執行的操作時,最好是啟動一個服務,而不是簡單的創建一個工作線程。尤其是當這個操作可能比activity的生命還要長時。例如,一個向網站上傳圖片的activity,應該啟動一個service,從而使上傳操作可以在用戶離開這個activity時繼續在後台執行。使用一個service保證了這個操作至少是在"服務進程"級別,而不用管activity是否發生了什麼不幸。這同樣是廣播接收者應該使用service而不是簡單地使用一個線程的理由。