android中线程和进程
當應用組件啟動且沒有運行其他組件時,Android系統會使用單個執行線程為應用啟動新的Linux進程。默認情況下,同一應用的所有組件在主線程中運行。若某個應用組件啟動且應用已存在進程,則該組件會在此進程內啟動并使用相同的執行線程。
默認情況下,同一應用的所有組件都在相同進程中進行,但若需要控制某個組件所屬的進程,則可以在清單文件中執行進行控制進程。
各類組件元素的清單文件條目<activity><service><receive><provider>均支持android:process屬性,可以指定該組件在哪個進程運行。可以設置此屬性,使每個組件在各自的進程中運行,或者使一些組件共享一個進程,還可以使不同的應用組件在相同的進程中進行,前提是這些應用共享相同的Linux用戶ID并使用相同IDE證書進行簽署。<appication>元素還支持android:process屬性,以設置適用于所有組件的默認值。
進程生命周期
進程的重要性層次結構:(層次越低越容易在回收內存時,被移除)
1.前臺進程---用戶當前操作的必須的進程:
托管用戶正在交互的Activity(已調用Activity的onResume()方法)
托管某個Service,后者綁定到用戶正在交互的Activity
托管正在”前臺“運行的Service(服務已調用startForeground())
托管正在執行一個生命周期回調的Service(onCreate(), onStart(), onDestroy())
托管正執行onReceive()方法的BroadcastReceiver
2.可見進程---沒有前臺組件,但仍會影響用戶在屏幕上所見內容的進程
托管不在前臺,但仍對用戶可見的Activity(調用onPause())
托管綁定在可見Activity的Service
3.服務進程
正在運行startService()方法啟動的服務
4.后臺進程
目前對用戶不可見的Activity進程(已調用Activity的onStop())
5.空進程
不含任何活動應用組件的進程,保留這種進程的唯一目的就是用作緩存,以縮短下次在其中運行組件啟動的時間。
線程
啟動應用時,系統會為應用創建一個”主線程“,負責將事件分派給相應的用戶界面小部件,其中包括繪圖事件,主線程也是應用與AndroidUI工具包組件進行交互的線程,故主線程有時也被成為UI線程。
不能通過工作線程操縱UI,而只能通過UI線程操縱用戶界面,故Android的單線程模式必須遵守兩條規則:
1.不要阻塞UI線程
2.不要在UI線程之外訪問AndroidUI工具包
工作線程
要保證應用UI 的響應能力,關鍵是不能阻塞UI線程,若執行的操作不能很快完成,則應該確保在單獨的線程中運行。
如,一個點擊偵聽器從單獨的線程下載圖像并將其顯示在ImageView中
public void onCLick(View v){ new Thread(new Runnable(){ public void run(){ Bitmap b = loadImageFromNetWork("http://example.com/image.png"); mImageView.setImageBitmap(b);}}).start(); } 創建了一個新線程來處理網絡操作,但上述代碼違反了單線程模式第二條規則,它從工作線程(而不是UI線程)修改了ImageView,可能導致出現不明確、不可預計的行為,而跟蹤此行為困難又費時。為解決此問題,Android提供了幾種途徑從其他線程訪問UI線程:
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
例如,可以使用View.post(Runnable)方法:
public void onClick(View v) {new Thread(new Runnable() {public void run() {final Bitmap bitmap =loadImageFromNetwork("http://example.com/image.png");mImageView.post(new Runnable() {public void run() {mImageView.setImageBitmap(bitmap);}});}}).start(); } 上述實現就是線程安全型,在單獨的線程中完成網絡操作,而在UI線程中操作ImageView。不過,操作越來越復雜,就需要通過工作線程處理更復雜的交互,可以在工作線程中使用Handler處理來自UI線程的消息,最好的解決辦法是擴展AsyncTask類,此類簡化了與UI進行交互所需執行的工作線程任務。
使用AsyncTask
AsyncTask允許對用戶界面執行異步操作,它會先阻塞工作線程中的操作,然后在UI線程中發布結果,而無需親自處理線程或處理程序。
使用時,必須創建AsyncTask的子類并實現doInBackground()回調方法,該方法將會在后臺線程池中運行,要更新UI,應該實現onPostExecute()以傳遞doInBackground()返回的結果并在UI線程中運行,以便安全地更新UI,隨后即可通過UI線程調用execute()來運行任務。
public void onCLick(View v){new DownloadImageTask().execute("http://example.com/image.png"); } private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>{protected Bitmap doInBackground(String... urls){return loadImageFromNetwork(urls[0]);}protected void onPostExecute(Bitmap result){mImageView.setImageBitmap(result);} }現在UI是安全的,代碼也簡化,由于任務被分解成兩部分,一部分在工作線程中完成,一部分在UI線程中完成。簡要概述AsyncTask的工作方法:
可以使用泛型指定參數類型,進度值和任務最終值
方法doInBackground()會在工作線程上自動執行
onPreExecute(), onPostExecute(), onProgressUpdate()均在UI線程中調用
doInBackground()返回的值將發送到onPostExecute()
可以隨時在doInBackground()中調用publishProgress(), 以在UI線程中執行onProgressUpdate()
可以隨時取消任何線程中的任務
進程間的通信
Android 利用遠程過程調用 (RPC) 提供了一種進程間通信 (IPC) 機制,通過這種機制,由 Activity 或其他應用組件調用的方法將(在其他進程中)遠程執行,而所有結果將返回給調用方。 這就要求把方法調用及其數據分解至操作系統可以識別的程度,并將其從本地進程和地址空間傳輸至遠程進程和地址空間,然后在遠程進程中重新組裝并執行該調用。 然后,返回值將沿相反方向傳輸回來。 Android 提供了執行這些 IPC 事務所需的全部代碼,因此您只需集中精力定義和實現 RPC 編程接口即可。
要執行IPC,必須使用bindService()將應用綁定到服務上。
總結
以上是生活随笔為你收集整理的android中线程和进程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JDBC详解及总结
- 下一篇: Android中BaseAdapter使