Android進程間通訊IPC

 

1、IPC的說明android

IPC是Inter-Process Communication的縮寫,含義爲進程間通訊或跨進程通訊,是指兩個進程之間進行數據交換的過程。git

IPC不是Android獨有的,任何一個操做系統都須要有相應的IPC機制,好比Windows上能夠經過剪貼板,管道和郵槽來進行進程間通訊;Linux上能夠經過命名管道、共享內容、信號量等進行進程間通訊。github

對於Android來講,它是一種基於Linux內核的移動操做系統,但它的進程間通訊方式並不能徹底繼承自Linux;相反,它有本身的進程間通訊方式。數據庫

在Android中能夠經過Binder輕鬆的實現進程間通訊。Android還支持Socket,經過Socket能夠實現任意兩個終端之間的通訊,同一設備的兩個進程經過Socket通訊天然也是能夠的。編程

 

2、Android中IPC的使用緩存

首先,只有面對多進程的狀況才須要考慮進程間通訊。多進程的狀況分爲兩種:服務器

第一種是一個應用由於某些緣由,自身須要採用多進程模式來實現,好比有些模塊須要運行在單獨的進程中、或者爲了加大一個應用的可以使用內存,須要經過多進程來獲取多份內存空間。網絡

另外一種是當前應用須要向其餘的應用獲取數據,因此必須採用跨進程的方式來獲取數據,好比使用系統的ContentProvider去查詢數據。併發

經過給四大組件在AndroidMenifest中指定android:process屬性,能夠輕易地開啓多進程模式。框架

 

3、Android中IPC帶來的問題

兩個應用共享數據:Android系統會爲每一個應用分配一個惟一的UID,具備相同UID的應用才能共享數據。兩個應用經過ShareUID跑在同一個進程是有要求的,須要這兩個應用有相同的ShareUID而且簽名相同才能夠。在這種狀況下,他們能夠相互訪問對方的私有數據,好比data目錄,組件信息等,無論他們是否跑在同一個進程。

Android系統爲每一個應用分配了一個獨立的虛擬機,或者說爲每個進程都分配一個獨立的虛擬機,不一樣的虛擬機在內存分配上有不一樣的地址空間,這就致使在不一樣的虛擬機中訪問同一個對象會產生多分副本。全部運行在不一樣進程中的四大組件,只要它們之間須要經過內存來共享數據,都會共享失敗,這也是多進程帶來的主要影響。

通常來講,使用多進程會形成以下的問題:

(1)靜態成員和單例模式徹底失效(不一樣的虛擬機中訪問同一個對象會產生多分副本)

(2)線程同步機制徹底失效(不在同一塊內存,無論是所對象仍是鎖全局類都沒法保證線程同步)

(3)SharePreferences的可靠性降低(不支持兩個進程同時寫操做)

(4)Application會屢次建立(由於建立新進程會分配獨立虛擬機,至關於啓動一個新的應用)

雖然說不能直接的共享內存,可是經過跨進程通訊仍是能夠實現數據交互。

 

4、Android中各類IPC方式

一、使用Bundle

四大組件中三大組件Activity、Service、Receiver都支持在Intent中傳遞Bundle數據。

因爲Bundle實現了Parcelable接口,因此它能夠很方便的在不一樣的進程間傳輸數據。固然咱們傳輸的數據必須可以被序列化,好比基本類型、實現了Parcelable接口的對象、實現了Serializable接口的對象以及一些Android支持的特殊對象。

二、使用文件共享

兩個進程經過讀寫同一個文件來交換數據,好比A進程把數據寫入文件,B進程經過讀取這個文件來獲取數據。

Android系統基於Linux,使得併發讀寫文件能夠沒有限制的進行,甚至兩個線程同時對文件讀寫操做都是容許的,儘管可能出問題,所以文件共享方式適合在對數據同步要求不高的進程間進行通訊。

SharedPreferences也屬於文件的一種,可是因爲系統對它的讀寫有必定的緩存策略,即在內存中會有一份SharedPreferences文件的緩存;所以在多進程模式下,系統對它的讀寫就變得不可靠,會有很大概率丟失數據,不建議在進程間通訊中使用SharedPreferences。

三、使用Messenger

Messenger能夠理解爲信使,經過它能夠再不一樣進程中傳遞Message對象,在Message中放入咱們須要傳遞的數據,就能夠實現數據的進程間傳遞了。

Messenger是一種輕量級的IPC方案,它的底層實現是AIDL。因爲它一次處理一個請求,所以在服務端不須要考慮線程同步的問題,由於服務端不存在併發執行的情形。

四、使用AIDL

AIDL是 Android Interface definition language的縮寫,它是一種android內部進程通訊接口的描述語言。AIDL能夠處理髮送到服務器端大量的併發請求(不一樣與Messenger的串行處理方式),也能夠實現跨進程的方法調用。

在Android中使用方法:建立一個Service和一個AIDL接口,接着建立一個類繼承自AIDL接口中的Stub類並實現Stub中的抽象方法,在Service的onBind方法中返回這個類的對象,而後客戶端綁定服務端Service,創建鏈接後就能夠訪問遠程服務器了。

五、使用ContentProvider

ContentProvider是Android中提供的專門用於不一樣應用間進行數據共享的方式,天生適合進程間通訊。

ContentProvider的底層實現也是Binder,可是它的使用過程比AIDL簡單的多,由於系統作了封裝,使得無需關心細節便可輕鬆實現IPC。ContentProvider主要以表格的形式組織數據,和數據庫很相似,但ContentProvider對底層的數據存儲方式沒有任何要求,既可使用Sqlite數據庫,也可使用文件方式,甚至可使用內存中的一個對象來存儲。

六、使用Socket

Socket套接字,是網絡通訊中的概念,分爲流式套接字和用戶數據奧套接字兩種,對應於網絡的傳輸控制層中的TCP和UDP協議。

兩個進程能夠經過Socket來實現信息的傳輸,Socket自己能夠支持傳輸任意字節流。

===選擇合適的IPC方式===,以下表

名稱 優勢 缺點 適用場景
Bundle 簡單易用 只能傳輸Bundle支持的數據類型 四大組件的進程間通訊
文件共享 簡單易用

不適合高併發場景,而且沒法作到進程間

即時通訊

無併發訪問清醒,交換簡單的數據,實時性不搞的場景
AIDL 功能強大,支持一對多併發通訊,支持實時通訊 使用稍複雜,須要處理好線程同步 一對多通訊且有RPC需求
Messenger 功能通常,支持一對多串行通訊,支持實時通訊 不能很好的處理高併發情形,不支持RPC,數據經過Message進行傳輸,所以只能傳輸Bundle支持的數據類型 低併發的一對多即時通訊,無RPC需求
ContentProvider

在數據源訪問方面功能強大,支持一對多併發數據共享,

可經過Call方法擴展其餘操做

能夠理解爲受約束的AICL,主要提供數據的CRUD數據 一對多的進程間數據共享
Socket 功能強大,能夠經過網絡傳輸字節流,支持一對多併發實時通訊 實現細節稍微繁瑣,不支持直接的RPC 網絡數據交換

RPC(Remote Procedure Call,遠程過程調用)是種C/S的編程模式,出於一種類比的願望,在一臺機器上運行的主程序,能夠調用另外一臺機器上準備好的子程序。

經過RPC能夠充分利用非共享內存的多處理器環境,能夠簡便地將你的應用分佈在多臺工做站上,應用程序就像運行在一個多處理器的計算機上同樣。

 

 5、Binder介紹

Binder是Android系統進程間通訊方式之一。Linux已經擁有的進程間通訊IPC手段包括: 管道(Pipe)、信號(Signal)、跟蹤(Trace)、插口(Socket)、報文隊列(Message)、共享內存(Share Memory)和信號量(Semaphore)。

Binder框架定義了四個角色:Server,Client,ServiceManager以及Binder驅動。

其中Server,Client,ServiceManager運行於用戶空間,驅動運行於內核空間。Binder就是一種把這四個組件粘合在一塊兒的粘結劑了,其中,核心組件即是Binder驅動程序了,Service Manager提供了輔助管理的功能,Client和Server正是在Binder驅動和Service Manager提供的基礎設施上,進行Client-Server之間的通訊。這四個角色的關係和互聯網相似:Server是服務器,Client是客戶終端,ServiceManager是域名服務器(DNS),驅動是路由器。

Binder的理解:

一、從IPC角度來講,Binder是Android中的一種跨進程通訊方式,該方式在Linux中沒有;

二、從Android Framework角度來講,Binder是ServiceManager鏈接各類Manager和相應ManagerService的橋樑;

三、從Android應用層來講,Binder是客戶端和服務端進行通許in的媒介,當BindService的時候,服務端會返回一個包含了服務端業務調用的Binder對象,經過這個Bind而對象,客戶端就能夠獲取服務端提供的服務或者數據,這裏的服務包括普通服務和基於AIDL的服務。

 

在Android開發中,Binder主要用在Service中,包括AIDL和Messenger,普通服務中的Binder不涉及進程間通訊。

直觀來說,Binder是Android中的一個類,實現了IBinder接口。

Binder的工做機制:

當客戶端發起遠程請求時,因爲當前線程會被掛起直至服務端進程返回數據,因此一個遠程方法是很耗時的,那麼不能在UI線程中發起此遠程請求;

因爲服務端的Binder方法運行在Binder的線程池中,因此Binder方法無論是否耗時都應該採用同步的方式去實現,由於它已經運行在一個線程中了。

 

6、具體實例

進程間通訊Demo實例

相關文章
相關標籤/搜索