国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Android 的進程與線程總結

移動開發 Android
當一個Android應用程序組件啟動時候,如果此時這個程序的其他組件沒有正在運行,那么系統會為這個程序以單一線程的形式啟動一個新的Linux 進程。 默認情況下,同一應用程序下的所有組件都運行再相同的進程和線程(一般稱為程序的“主”線程)中。如果一個應用組件啟動但這個應用的進程已經存在了(因為 這個應用的其他組件已經在之前啟動了),那么這個組件將會在這個進程中啟動,同時在這個應用的主線程里面執行。然而,你也可以讓你的應用里面的組件運行在 不同的進程里面,也可以為任何進程添加額外的線程。

本文翻譯自Android官方文檔

當一個Android應用程序組件啟動時候,如果此時這個程序的其他組件沒有正在運行,那么系統會為這個程序以單一線程的形式啟動一個新的Linux 進程。 默認情況下,同一應用程序下的所有組件都運行再相同的進程和線程(一般稱為程序的“主”線程)中。如果一個應用組件啟動但這個應用的進程已經存在了(因為這個應用的其他組件已經在之前啟動了),那么這個組件將會在這個進程中啟動,同時在這個應用的主線程里面執行。然而,你也可以讓你的應用里面的組件運行在 不同的進程里面,也可以為任何進程添加額外的線程。

這片文章討論了Android程序里面的進程和線程如何運作的。

進程

默認情況下,同一程序的所有組件都運行在相同的進程里面,大多數的應用都是這樣的。然而,如果你發現你需要讓你的程序里面的某個組件運行在特定的進程里面,你可以在manifest 文件里面設置。

manifest 文件里面為每一個組件元素—<activity><service><receiver>, 和<provider>—提供了 android:process 屬 性。通過設置這個屬性你可以讓組件運行在特定的進程中。你可以設置成每個組件運行在自己的進程中,也可以讓一些組件共享一個進程而其他的不這樣。你還可以 設置成不同應用的組件運行在同一個進程里面—這樣可以讓這些應用共享相同的Linux user ID同時被相同的證書所認證。

<application> 元素也支持 android:process 屬性,設置這個屬性可以讓這個應用里面的所有組件都默認繼承這個屬性。

Android 可能在系統剩余內存較少,而其他直接服務用戶的進程又要申請內存的時候shut down 一個進程, 這時這個進程里面的組件也會依次被kill掉。當這些組件有新的任務到達時,他們對應的進程又會被啟動。

在決定哪些進程需要被kill的時候,Android系統會權衡這些進程跟用戶相關的重要性。比如,相對于那些承載這可見的activities的 進程,系統會更容易的kill掉那些承載不再可見activities的進程。決定是否終結一個進程取決于這個進程里面的組件運行的狀態。下面我們會討論 kill進程時所用到的一些規則。

進程的生命周期

作為一個多任務的系統,Android 當然系統能夠盡可能長的保留一個應用進程。但是由于新的或者更重要的進程需要更多的內存,系統不得不逐漸終結老的進程來獲取內存。為了聲明哪些進程需要保 留,哪些需要kill,系統根據這些進程里面的組件以及這些組件的狀態為每個進程生成了一個“重要性層級” 。處于***重要性層級的進程將會***時間被清楚,接著時重要性高一點,然后依此類推,根據系統需要來終結進程。

在這個重要性層級里面有5個等級。下面的列表按照重要性排序展示了不同類型的進程(***種進程是最重要的,因此將會在***被kill):

  1. Foreground 進程 一個正在和用戶進行交互的進程。 如果一個進程處于下面的狀態之一,那么我們可以把這個進程稱為 foreground 進程:

    一般說來,任何時候,系統中只存在少數的 foreground 進程。 只有在系統內存特別緊張以至于都無法繼續運行下去的時候,系統才會通過kill這些進程來緩解內存壓力。在這樣的時候系統必須kill一些 (Generally, at that point, the device has reached a memory paging state,這句如何翻譯較好呢)foreground 進程來保證 用戶的交互有響應。

  2. Visible 進程 一個進程沒有任何 foreground 組件, 但是它還能影響屏幕上的顯示。 如果一個進程處于下面的狀態之一,那么我們可以把這個進程稱為 visible 進程:
    • 進程包含了一個沒有在foreground 狀態的 Activity ,但是它仍然被用戶可見 (它的 onPause() 方法已經被調用)。這種情況是有可能出現的,比如,一個 foreground activity 啟動了一個 dialog,這樣就會讓之前的 activity 在dialog的后面部分可見。
    • 進程包含了一個綁定在一個visible(或者foreground)activity的 Service 。

    一個 visible 進程在系統中是相當重要的,只有在為了讓所有的foreground 進程正常運行時才會考慮去kill visible 進程。

  3. Service 進程 一個包含著已經以 startService() 方法啟動的 Service 的 進程,同時還沒有進入上面兩種更高級別的種類。盡管 service 進程沒有與任何用戶所看到的直接關聯,但是它們經常被用來做用戶在意的事情(比如在后臺播放音樂或者下載網絡數據),所以系統也只會在為了保證所有的 foreground and visible 進程正常運行時kill掉 service 進程。
  4. Background 進程 一個包含了已不可見的activity的 進程 (這個 activity 的 onStop() 已 經被調用)。這樣的進程不會直接影響用戶的體驗,系統也可以為了foreground 、visible 或者 service 進程隨時kill掉它們。一般說來,系統中有許多的 background 進程在運行,所以將它們保持在一個LRU (least recently used)列表中可以確保用戶最近看到的activity 所屬的進程將會在***被kill。如果一個 activity 正確的實現了它的生命周期回調函數,保存了自己的當前狀態,那么kill這個activity所在的進程是不會對用戶在視覺上的體驗有影響的,因為當用戶 回退到這個 activity時,它的所有的可視狀態將會被恢復。查看 Activities 可以獲取更多如果保存和恢復狀態的文檔。
  5. Empty 進程 一個不包含任何活動的應用組件的進程。 這種進程存在的唯一理由就是緩存。為了提高一個組件的啟動的時間需要讓組件在這種進程里運行。為了平衡進程緩存和相關內核緩存的系統資源,系統需要kill這些進程。

Android是根據進程中組件的重要性盡可能高的來評級的。比如,如果一個進程包含來一個 service 和一個可見 activity,那么這個進程將會被評為 visible 進程,而不是 service 進程。

另外,一個進程的評級可能會因為其他依附在它上面的進程而被提升—一個服務其他進程的進程永遠不會比它正在服務的進程評級低的。比如,如果進程A中 的一個 content provider 正在為進程B中的客戶端服務,或者如果進程A中的一個 service 綁定到進程B中的一個組件,進程A的評級會被系統認為至少比進程B要高。

因為進程里面運行著一個 service 的評級要比一個包含background activities的進程要高,所以當一個 activity 啟動長時操作時,***啟動一個 service 來 做這個操作,而不是簡單的創建一個worker線程—特別是當這個長時操作可能會拖垮這個activity。比如,一個需要上傳圖片到一個網站的 activity 應當開啟一個來執行這個上傳操作。這樣的話,即使用戶離開來這個activity也能保證上傳動作在后臺繼續。使用 service 可以保證操作至少處于”service process” 這個優先級,無論這個activity發生了什么。這也是為什么 broadcast receivers 應該使用 services 而不是簡單的將耗時的操作放到線程里面。

線程

當一個應用啟動的時候,系統會為它創建一個線程,稱為“主線程”。這個線程很重要因為它負責處理調度事件到相關的 user interface widgets,包括繪制事件。你的應用也是在這個線程里面與來自Android UI toolkit (包括來自 android.widget 和 android.view 包的組件)的組件進行交互。因此,這個主線程有時候也被稱為 UI 線程。

系統沒有為每個組件創建一個單獨的線程。同一進程里面的所有組件都是在UI 線程里面被實例化的,系統對每個組件的調用都是用過這個線程進行調度的。所以,響應系統調用的方法(比如 onKeyDown() 方法是用來捕捉用戶動作或者一個生命周期回調函數)都運行在進程的UI 線程里面。

比如,當用戶點擊屏幕上的按鈕,你的應用的UI 線程會將這個點擊事件傳給 widget,接著這個widget設置它的按壓狀態,然后發送一個失效的請求到事件隊列。這個UI 線程對請求進行出隊操作,然后處理(通知這個widget重新繪制自己)。

當你的應用與用戶交互對響應速度的要求比較高時,這個單線程模型可能會產生糟糕的效果(除非你很好的實現了你的應用)。特別是,當應用中所有的事情 都發生在UI 線程里面,那些訪問網絡數據和數據庫查詢等長時操作都會阻塞整個UI線程。當整個線程被阻塞時,所有事件都不能被傳遞,包括繪制事件。這在用戶看來,這個 應用假死了。甚至更糟糕的是,如果UI 線程被阻塞幾秒(當前是5秒)以上,系統將會彈出臭名昭著的 “application not responding” (ANR) 對話框。這時用戶可能選擇退出你的應用甚至卸載。

另外,Android的UI 線程不是線程安全的。所以你不能在一個worker 線程操作你的UI—你必須在UI線程上對你的UI進行操作。這有兩條簡單的關于Android單線程模型的規則:

  1. 不要阻塞 UI 線程
  2. 不要在非UI線程里訪問 Android UI toolkit

Worker 線程

由于上面對單一線程模型的描述,保證應用界面的及時響應同時UI線程不被阻塞變得很重要。如果你不能讓應用里面的操作短時被執行玩,那么你應該確保把這些操作放到獨立的線程里(“background” or “worker” 線程)。

比如,下面這段代碼在一個額外的線程里面下載圖片并在一個 ImageView顯示:

  1. new Thread(new Runnable(){ 
  2.     public void run(){ 
  3.         Bitmap b = loadImageFromNetwork("http://example.com/image.png"); 
  4.         mImageView.setImageBitmap(b); 
  5.     } 
  6. }).start();} 

起先這段代碼看起來不錯,因為它創建一個新的線程來處理網絡操作。然而,它違反來單一線程模型的第二條規則: 不在非UI線程里訪問 Android UI toolkit—這個例子在一個worker線程修改了 ImageView 。這會導致不可預期的結果,而且還難以調試。

為了修復這個問題,Android提供了幾個方法從非UI線程訪問Android UI toolkit 。詳見下面的這個列表:

那么,你可以使用 View.post(Runnable) 方法來修改之前的代碼:

  1. public void onClick(View v){ 
  2.     new Thread(new Runnable(){ 
  3.         public void run(){ 
  4.             final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png"); 
  5.             mImageView.post(new Runnable(){ 
  6.                 public void run(){ 
  7.                     mImageView.setImageBitmap(bitmap); 
  8.                 } 
  9.             }); 
  10.         } 
  11.     }).start();} 

現在這個方案的線程安全的:這個網絡操作在獨立線程中完成后,UI線程便會對ImageView 進行操作。

然而,隨著操作復雜性的增長,代碼會變得越來越復雜,越來越難維護。為了用worker 線程處理更加復雜的交互,你可以考慮在worker線程中使用Handler ,用它來處理UI線程中的消息。也許***的方案就是繼承 AsyncTask 類,這個類簡化了需要同UI進行交互的worker線程任務的執行。

使用 AsyncTask

AsyncTask 能讓你在UI上進行異步操作。它在一個worker線程里進行一些阻塞操作然后把結果交給UI主線程,在這個過程中不需要你對線程或者handler進行處理。

使用它,你必須繼承 AsyncTask 并實現 doInBackground() 回調方法,這個方法運行在一個后臺線程池里面。如果你需要更新UI,那么你應該實現onPostExecute(),這個方法從 doInBackground() 取出結果,然后在 UI 線程里面運行,所以你可以安全的更新你的UI。你可以通過在UI線程調用 execute()方法來運行這個任務。

比如,你可以通過使用 AsyncTask來實現之前的例子:

  1. public void onClick(View v){ 
  2.     new DownloadImageTask().execute("http://example.com/image.png"); 
  3. private class DownloadImageTask extends AsyncTask<String,Void,Bitmap>{ 
  4.     /** The system calls this to perform work in a worker thread and 
  5.       * delivers it the parameters given to AsyncTask.execute() */ 
  6.     protected Bitmap doInBackground(String... urls){ 
  7.         return loadImageFromNetwork(urls[0]); 
  8.     } 
  9.     
  10.     /** The system calls this to perform work in the UI thread and delivers 
  11.       * the result from doInBackground() */ 
  12.     protected void onPostExecute(Bitmap result){ 
  13.         mImageView.setImageBitmap(result); 
  14.     }} 

現在UI是安全的了,代碼也更加簡單了,因為AsyncTask把worker線程里做的事和UI線程里要做的事分開了。

你應該閱讀一下 AsyncTask 的參考文檔以便更好的使用它。下面就是一個對 AsyncTask 如何作用的快速的總覽:

注意: 你在使用worker線程的時候可能會碰到的另一個問題就是因為runtime configuration change (比如用戶改變了屏幕的方向)導致你的activity不可預期的重啟,這可能會kill掉你的worker線程。為了解決這個問題你可以參考 Shelves 這個項目。

線程安全的方法

在某些情況下,你實現的方法可能會被多個線程所調用,因此你必須把它寫出線程安全的。

[[124306]]

文地址:Android的進程與線程

責任編輯:閆佳明 來源: greenrobot.me
相關推薦

2018-07-06 14:00:55

Linux進程線程

2018-05-31 10:57:31

Linux系統進程線程

2015-09-08 15:13:35

Android進程與線程

2009-09-16 08:43:51

linux進程線程

2012-05-04 09:49:34

進程

2021-05-21 09:36:42

開發技能代碼

2022-06-07 07:37:40

線程進程開發

2022-02-07 11:55:00

linux進程線程

2022-05-26 08:31:41

線程Java線程與進程

2019-06-03 09:13:11

線程進程多線程

2013-04-25 09:55:21

進程線程

2012-06-20 14:07:28

多線程架構單線程

2025-11-25 07:15:00

2019-02-26 11:15:25

進程多線程多進程

2011-07-25 10:00:59

項目

2019-09-18 15:09:50

進程線程操作系統

2022-10-12 09:01:52

Linux內核線程

2021-06-11 11:28:22

多線程fork單線程

2025-05-06 09:12:46

2023-03-05 16:12:41

Linux進程線程
點贊
收藏

51CTO技術棧公眾號

欧美午夜激情在线| 成av人片一区二区| 日韩中文第一页| 粉嫩13p一区二区三区| 国产91色在线|免| 开心丁香婷婷深爱五月| 久久久久久久| 欧美插天视频在线播放| 97超碰资源站在线观看| 午夜精品视频一区| 免费福利片在线观看| 91在线国内视频| 免费一级特黄特色毛片久久看| 另类调教123区| 日韩在线三区| 日韩国产在线一| 日本视频一区二区在线观看| 亚洲欧美日韩精品一区二区 | 中文av一区| 1卡2卡3卡精品视频| 午夜av一区| 97se在线视频| 亚洲激情影院| 欧美精品一区二区三区在线看午夜 | 久久99精品久久久久久久青青日本 | 一区二区三区精品国产| 青青草视频一区| 一区二区三区四区| 久久99精品国产麻豆婷婷| 久久久国产精华液999999| 久久97超碰国产精品超碰| 久久久一二三四| 国产一区二区伦理片| www.激情网| www亚洲一区| 猫咪成人官网| 亚洲卡通欧美制服中文| 伊人中文字幕在线| 7777精品伊人久久久大香线蕉完整版| 成人福利影视| 久久这里只有精品视频首页| 亚洲综合图色| 俄罗斯精品一区二区| 日韩黄色片在线观看| 青青草视频在线视频| 久久精品视频一区二区| 超碰色偷偷男人的天堂| 日本久久电影网| 丰满大乳少妇在线观看网站| 日韩一区二区精品视频| 在线看成人短视频| 99免费在线观看视频| 天堂va蜜桃一区二区三区 | 亚洲色图第三页| 四虎视频在线精品免费网址| 日韩免费中文字幕| 国产欧美日本| 无码精品a∨在线观看中文| 一级特黄大欧美久久久| 黄色网页在线观看| 欧美老少做受xxxx高潮| 欧美日韩网址| 99精品在线免费视频| 亚洲国产日产av| 黑人玩欧美人三根一起进| 欧美成人免费一级人片100| 日韩在线观看| 亚洲精品偷拍视频| 一区二区三区视频在线看| 金瓶狂野欧美性猛交xxxx| 2018日韩中文字幕| 老司机精品福利视频| 7878视频在线观看| 欧美变态tickling挠脚心| 老司机精品在线| 久久免费一区| 国产精品女主播av| 678在线观看视频| 国产精品九九九| 国产乱码精品一区二区三| 伊人网在线免费观看| 色狠狠久久aa北条麻妃| 激情另类综合| 国产性一级片| 在线国产精品播放| 国产日韩专区| 一级一片免费视频| 美女精品久久久| 日本不卡视频一二三区| 羞羞视频在线观看| 欧美裸身视频免费观看| 久久九九国产| 超碰在线94| 成人97在线观看视频| 久久激情一区| 亚洲电影小说图| 久久久久久国产三级电影| 精品一区二区在线免费观看| 国产精品久久一区二区三区不卡 | 天堂中文av在线资源库| 91欧美激情另类亚洲| 久久综合九色综合欧美就去吻| 色呦呦在线看| 国产v亚洲v天堂无码| 亚洲视频综合在线| 国产精久久久| 菠萝蜜视频在线观看入口| 日韩一区二区中文字幕| 女厕盗摄一区二区三区| 国产极品在线视频| 欧美精品在线一区二区| 噼里啪啦国语在线观看免费版高清版| 欧美高清精品3d| 精品大片一区二区| 国产精品拍拍拍| 亚洲性无码av在线| 老司机精品视频网站| aaa日本高清在线播放免费观看| 国产精品久久久久久影视| 国产日韩亚洲欧美综合| 狠狠久久伊人中文字幕| 综合操久久久| 亚洲精品www| 美女视频黄 久久| 麻豆tv免费在线观看| 成人欧美一区二区| 91国偷自产一区二区使用方法| 欧美日韩一区二区综合| 国产私人影院| 国产精品视频一区国模私拍| 怡红院av一区二区三区| 精品国产一区二区三区久久久樱花 | 国产精品中文久久久久久久| 国产精品国产三级国产aⅴ中文 | 天天色综合天天色| 欧美精品电影在线| 欧美国产日韩亚洲一区| 91麻豆精品激情在线观看最新 | 国产日产一区| 香港经典三级在线| 国产日韩精品综合网站| 五月开心婷婷久久| 97国产成人高清在线观看| 在线播放三级网站| 国产成人精品免费视频大全最热| 欧美无砖专区一中文字| 亚洲制服av| 欧洲一级精品| 中文久久久久久| 国产z一区二区三区| 欧美日韩美女在线观看| 国产精品永久| 欧美日韩五码| 激情亚洲综合网| 91夜夜未满十八勿入爽爽影院| 色88888久久久久久影院按摩| 亚洲欧美视频一区二区三区| 怡红院成人在线| 国内外成人免费在线视频| 国产日韩欧美夫妻视频在线观看 | 日韩二区三区| 精品免费日产一区一区三区免费| 欧美v日韩v国产v| 成人动漫中文字幕| 国产乱码精品一区二区三区四区 | 中文成人激情娱乐网| 日本成人a视频| 成人动漫在线观看视频| 日韩国产欧美精品在线| 国产三级一区二区| 综合国产精品| 欧美色网一区| 亚洲欧美国产日韩综合| 国产亚洲美州欧州综合国| 成人在线观看免费视频| 人成网站免费观看| 日韩欧美亚洲日产国产| 两个人的视频www国产精品| 亚洲va欧美va国产va天堂影院| 视频一区欧美精品| 好吊妞视频这里有精品| 免费a级毛片在线播放| 无码aⅴ精品一区二区三区浪潮| 国产免费一区二区三区香蕉精| 日韩久久久久久| 国产精品剧情在线亚洲| 一区二区三区四区五区精品视频 | 久久精品夜色噜噜亚洲a∨| 中文字幕精品在线不卡| 精品视频一区在线视频| 国产国产精品人在线视| 91成人在线看| 丝袜足脚交91精品| 老鸭窝一区二区久久精品| 欧美精品影院| 黄色视屏网站在线免费观看| 国产麻豆午夜三级精品| 欧洲av一区二区嗯嗯嗯啊| 午夜视频一区| 成人免费视频77777|