Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android的進程和線程機制(一)——進程

Android的進程和線程機制(一)——進程

編輯:關於Android編程

對於一個Android應用程序來說,當它的某個組件開始運行時,此時如果該應用沒有其他組件已經在運行,Android系統會為該應用開辟一個新的單線程的Linux進程。默認情況下,該應用的所有組件都會運行在這個進程和線程中,此時這個進程的唯一線程被稱作“main”線程即主線程。如果這個應用的其他組件啟動時該應用的進程已經存在(即已經有該應用的其他組件在運行),那麼新的組件就會在已經存在的進程中啟動並使用主線程來執行。然而,我們也可以為同一個應用的不同組件開辟不同的進程,並且可以為每個進程創建額外的線程。

進程

默認情況下,同一個應用的所有組件運行在同一個進程中,這對於多數應用來說是足夠的。然而,當我們需要對應用的組件所屬的進程作出更細的控制時,我們可以在AndroidManifest.xml文件中進行指定。AndroidManifest.xml文件中,對於每個組件元素——、,都有一個android:process屬性可以指定組件的運行進程。通過這個屬性,我們可以指定每個組件運行在獨立的進程中或部分組件共享一個進程。如果不同應用共享同一個Linux用戶ID並且擁有相同的證書,我們還可以通過android:process屬性指定跨應用的不同組件共享一個進程。

AndroidManifest.xml文件中,元素也支持android:process屬性,我們可以在這裡設置一個默認的進程為該應用的所有組件共享。當系統內存不足而其他急需與用戶進行交互的進程需要內存時,Android系統可能會在某一時刻選擇關閉一些進程以釋放資源為新進程服務。此時,運行在這些進程裡的組件也會被銷毀,當再次啟動這些組件時此時會開辟新的進程。這一點是我們需要注意的,之前的數據就會丟失。至於系統會選擇哪些進程來殺死,這取決於這些進程對於用戶的重要性,系統會計算這個權重來排序。比如,相對於當前尚有處於可視狀態的Activity的進程來說,那些只有組件在後台運行的進程就會更容易被系統殺死。因此,是否要終止一個進程是取決於該進程當前運行的組件的狀態。


進程的生命周期
在資源充足的情況下,Android系統會盡量維系一個應用進程的存活時間,但系統總會有資源緊張的時候,當有新的更重要的進程申請資源的時候系統就會移除掉一些相對來說不再重要的舊進程以釋放資源騰出空間給新的更重要的進程來使用。在決定哪些進程要被殺死,哪些進程要被保留時,系統會根據每個進程中所運行的組件及其狀態來計算一個權重值並進行排序,那麼那些重要性最低的進程就會首先被移除掉,然後是次低重要性的進程,以此類推,直至釋放出了必需的資源。進程重要性的級別被劃分為5個等級。下面按照從高到低依次進行詳細說明(重要性最高的進程將最後被殺死):
前台進程
所謂前台進程,指的是當前正在與用戶進行交互的進程。當下面的條件滿足任何一個時,該進程就會被認為是前台進程:
1、該進程有一個Activity正在與用戶進行交互,即該Activity正處於onResume()狀態時;
2、該進程有一個Service與當前用戶正在進行交互的Activity綁定;
3、該進程有一個Service正在前台運行,即該Service的startForeground()方法被調用;
4、該進程有一個Service的生命周期回調方法(onCreate()、onStart()或onDestroy())正在被調用;
5、該進程有一個BroadcastReceiver正在執行其onReceive()方法。
一般來說,任何一個時間點上系統運行的前台進程都不會很多。而這些前台進程除非是在系統內存嚴重不足甚至到了不能滿足這些前台進程運行的情況下才會被殺死。它們是系統殺死的最後選擇。一般來說,這種情況一般發生在系統已經到了內存分頁的狀態,只有殺死一部分前台進程才能保證對用戶的操作作出響應。

可視進程
所謂可視進程,指的是雖然當前沒有處於前台的組件但仍然能夠影響到呈現給用戶的視圖的進程。以下條件滿足任何一個時,該進程就可以被認為是可視進程:
1、該進程有一個Activity雖然不在前台,但用戶此時仍然能夠看到,即該Activity處於onPause()狀態,比如當前直接與用戶交互的Activity打開了一個對話框,則該Activity就會被對話框罩住,但仍然是可視的;
2、該進程有一個Service與一個可視的或前台的Activity綁定。
可視進程對系統來說也是非常重要的,除非只有殺死它才能保證所有的前台進程能夠正常運行時系統才會去殺死可視進程。
服務進程
所謂服務進程,指的是運行著一個通過startService()方法啟動的Service組件而尚未成為可視進程和前台進程的進程。盡管服務進程並未直接與用戶界面相關聯,但它們所執行的動作卻是用戶關心的(比如在後台播放音樂或是下載網絡數據),因此除非沒有足夠的內存來支撐這些服務進程以及所有的前台進程和可視進程的運行系統才會殺死服務進程。
後台進程
所謂後台進程,指的是擁有一個當前對用戶不可視的Activity在運行(即該Activity處於onStop()狀態)的進程。此類進程不再直接影響用戶界面,系統可在前台進程、可視進程或服務進程需要資源時系統內存不足的情況下隨時殺死後台進程。通常系統會有很多後台進程在運行,這些後台進程被系統以一個LRU(最近最少使用)列表所維護著以確保最後與用戶進行交互的Activity所在的進程被最後殺死。如果正確地實現了一個Activity的各個生命周期方法並保存了當前的狀態數據的話,那麼殺死該Activity所在的進程就不會對用戶界面產生任何可視的影響。因為當用戶再次返回到該Activity時,它會恢復自己的所有可視狀態數據。

空進程
所謂空進程,指的是沒有任何活躍的組件在運行的進程。此類進程存活的唯一目的是為了緩存的考慮,以在下次該進程的某個組件運行時可以快速啟動。系統會在進程緩存和內核緩存之間作出系統總體資源的平衡以決定是否殺死空進程。基於進程當前活躍的組件的重要性,Android系統會以組件的最高重要性為准來標識該進程的重要性。比如,如果一個進程擁有一個Service和一個可視的Activity,那麼該進程就會被標識為可視進程而不是服務進程。
此外,一個進程的重要性也可能會被提升如果有其他進程依賴於它,即該進程是服務於其他進程的,因此不可能會比它所服務的進程的重要性低。比如,進程A中的一個ContentProvider組件服務於進程B的客戶端,或進程A中的一個Service組件與進程B中的一個組件綁定,則進程A的重要性最低會與進程B的重要性相等。


因為運行Service組件的進程重要性要高於運行後台Activity的進程,因此對於一個Activity來說,與其開啟一個工作線程來執行一個常駐操作不如啟動一個Service來做這件事,特別是在該操作的生命周期要長於這個Activity的時候。比如,一個需要上傳圖片的Activity應該啟動一個Service來執行這個上傳操作,這樣即使用戶離開了該Activity上傳操作也能繼續在後台執行。使用Service組件來執行一些耗時的操作能夠保證這個操作最少擁有服務進程的優先級,而不用管Activity界面的狀態如何。這也是為什麼BroadcastReceiver應該使用Service而不是開啟一個線程執行耗時操作的同樣的原因。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved