Android進程與線程

來源:互聯網
上載者:User

當某個組件第一次啟動並執行時候,Android啟動了一個進程。預設的,所有的組件和程式運行在這個進程和線程中。

也可以安排組件在其他的進程或者線程中運行

進程

組件啟動並執行進程由manifest file控制。組件的節點 — <activity>, <service>, <receiver>, 和 <provider> — 都包含一個 process 屬性。這個屬性可以設定組件啟動並執行進程:可以配置組件在一個獨立進程運行,或者多個組件在同一個進程運行。甚至可以多個程式在一個進程中運行——如果這些程式共用一個User ID並給定同樣的許可權。<application> 節點也包含 process 屬性,用來設定程式中所有組件的預設進程。

所有的組件在此進程的主線程中執行個體化,系統對這些組件的調用從主線程中分離。並非每個對象都會從主線程中分離。一般來說,響應例如View.onKeyDown()使用者操作的方法和通知的方法也在主線程中運行。這就表示,組件被系統調用的時候不應該長時間運行或者阻塞操作(如網路操作或者計算大量資料),因為這樣會阻塞進程中的其他組件。可以把這類操作從主線程中分離。

當更加常用的進程無法擷取足夠記憶體,Android可能會關閉不常用的進程。下次啟動程式的時候會重新啟動進程。

當決定哪個進程需要被關閉的時候, Android會考慮哪個對使用者更加有用。如Android會傾向於關閉一個長期不顯示在介面的進程來支援一個經常顯示在介面的進程。是否關閉一個進程決定於組件在進程中的狀態,參見後面的章節Component Lifecycles.

線程

即使為組件分配了不同的進程,有時候也需要再分配線程。比如使用者介面需要很快對使用者進行響應,因此某些費時的操作,如網路連接、下載或者非常佔用伺服器時間的操作應該放到其他線程。

線程通過java的標準對象Thread 建立. Android 提供了很多方便的管理線程的方法:— Looper 線上程中運行一個訊息迴圈; Handler 傳遞一個訊息; HandlerThread 建立一個帶有訊息迴圈的線程。

遠程調用Remote procedure calls

Android有一個遠程調用(RPCs) 的輕量級機制— 通過這個機制,方法可以在本地調用,在遠程執行(在其他進程執行),還可以返回一個值。要實現這個需求,必須分解方法調用,並且所有要傳遞的資料必須是作業系統可以訪問的層級。從本地的進程和記憶體位址傳送到遠端進程和記憶體位址並在遠端和返回。傳回值必須向相反的方向傳遞。Android提供了做以上操作的代碼,所以開發人員可以專註於實現RPC的介面。

一個RPC介面只能包含方法。所有的方法都是同步執行的(直到遠程方法返回,本地方法才結束阻塞),沒有傳回值的時候也是如此。

簡單來說,這個機制是這樣的:使用IDL (interface definition language)定義你想要實現的介面, aidl 工具可以產生用於java的介面定義,本地和遠程都要使用這個定義。它包含2個類,見:

inner類包含了所有的管理遠程程式(符合IDL描述的介面)所需要的代碼。所有的inner類實現了IBinder 介面.其中一個在本地使用,可以不管它的代碼;另外一個叫做Stub繼承了 Binder 類。為了實現遠程調用,這個類包含RPC介面。開發人員可以繼承Stub類來實現需要的方法

一般來說,遠程進程會被一個service管理(因為service可以通知作業系統這個進程的資訊並和其他進程通訊),它也會包含aidl 工具產生的介面檔案,Stub類實現了遠處那個方法。服務的用戶端只需要aidl 工具產生的介面檔案。

以下是如何串連服務和用戶端調用:

  • ·服務的用戶端(本地)會實現onServiceConnected() 和onServiceDisconnected() 方法,這樣,當用戶端串連或者中斷連線的時候可以擷取到通知。通過 bindService() 擷取到服務的串連。
  • · 服務的 onBind() 方法中可以接收或者拒絕串連,取決它收到的intent (intent通過 bindService()方法串連到服務). 如果服務接收了串連,會返回一個Stub類的執行個體.
  • · 如果服務接受了串連,Android會調用用戶端的onServiceConnected() 方法,並傳遞一個Ibinder對象(系統管理的Stub類的代理),通過這個代理,用戶端可以串連遠端服務。

以上的描述省略很多RPC的機制。請參見Designing a Remote Interface Using AIDL 和 IBinder 類。

安全執行緒的方法

在某些情況下,方法可能調用不止一個的線程,因此需要注意方法的安全執行緒。

對於可以遠程調用的方法,也要注意這點。當一個調用在Ibinder對象中的方法的程式啟動了和Ibinder對象相同的進程,方法就在Ibinder的進程中執行。但是,如果調用者發起另外一個進程,方法在另外一個線程中運行,這個線程在和IBinder對象在一個線程池中;它不會在進程的主線程中運行。例如,一個service從主線程被調用onBind() 方法,onBind() 返回的對象(如實現了RPC的Stub子類)中的方法會被從線程池中調用。因為一個服務可能有多個用戶端請求,不止一個線程池會在同一時間調用IBinder的方法。因此IBinder必須安全執行緒。

簡單來說,一個content provider 可以接收其他進程的資料請求。即使ContentResolver和ContentProvider類沒有隱藏了管理互動的細節,ContentProvider中響應這些請求的方法(query(), insert(), delete(), update(), and getType() )— 是在content provider的線程池中被調用的,而不是ContentProvider的本身進程。因為這些方法可能是同時從很多線程池啟動並執行,所以這些方法必須要安全執行緒。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.