進程通訊是應用程序進程之間經過操做系統交換數據與服務對象的機制。Linux操做系統的傳統進程間通訊(IPC)有多種方式,好比管道,命令管道,信號量,共享內存,消息隊列,以及網絡與Unix套接字等。雖然理論上Android系統仍然可使用傳統的Linux進程通訊機制,可是在實際中,Android的應用程序幾乎不使用這些傳統方式。在Android的應用程序設計架構下,甚至看不到進程的概念,取而代之的是從組件的角度,如Intent,Activity,Service,Content Provider,實現組件之間的相互通訊。Android應用程序一般由一系列Activity和Service組成的,通常Service運行在獨立的進程中, Activity既可能運行在同一個進程中,也可能運行在不一樣的進程中。在不一樣進程中的Activity和Service要協做工做,實現完整的應用功能,必須進行通訊,以獲取數據與服務。這就回歸到歷史久遠的Client-Server模式。基於Client-Server的計算模式普遍應用於分佈式計算的各個領域,如互聯網,數據庫訪問等。在嵌入式智能手持設備中,爲了以統一模式嚮應用開發者提供功能,這種Client-Server方式無處不在。Android系統中的媒體播放,音視頻設備,傳感器設備(加速度,方位,溫度,光亮度等)由不一樣的服務端(Server)負責管理,使用服務的應用程序只要做爲客戶端(Client)向服務端(Server)發起請求便可。java
可是,Client-Server方式對進程間通訊機制在效率與安全性方面都是挑戰。數據庫
效率問題。傳統的管道,命名管道,網絡與UNIX套接字,消息隊列等須要屢次複製數據(數據先從發送進程的用戶區緩存複製到內核區緩存中,而後再從內核緩存複製到接收進程的用戶區緩存中,單向傳輸至少有兩次複製),系統開銷大。傳統的共享內存(shmem)機制無需將數據從用戶空間到內核空間反覆複製,屬於低層機制,但應用程序直接控制十分複雜,於是難以使用。編程
安全問題。傳統進程通訊機制缺少足夠的安全措施:首先,傳統進程通訊的接收進程沒法得到發送進程可靠的用戶標識/進程標識(UID/PID),於是沒法鑑別對方身份。Android的應用程序有本身UID,可用於鑑別進程身份。在傳統進程通訊中,只能由發送進程在請求中自行填入UID與PID,容易被惡意程序利用,是不可靠的。只有內置在進程通訊機制內的可靠的進程身份標記才能提供必要的安全保障。其次,傳統進程通訊的訪問接入點是公開的,如FIFO與unix domain socket的路徑名,socket的ip地址與端口號,lSystem V鍵值等,知道這些接入點的任何程序均可能試圖創建鏈接,很難阻止惡意程序得到鏈接,如經過猜想地址得到鏈接等。緩存
Android基於Dianne Hackborm的OpenBinder實現,引入Binder機制以知足系統進程通訊對性能效率和安全性的要求。Binder基於Client-Server通訊模式,數據對象只需一次複製,而且自動傳輸發送進程的UID/PID信息,同時支持實名Binder與匿名Binder。Binder其實提供了遠程過程調用(RPC)功能,概念上相似於COM和CORBA分佈式組件架構。對於熟悉Linux環境的程序設計者而言,從Linux意義的進程通訊角度來看,Android的進程通訊原理以下圖所示:安全
Binder進程通訊機制由一系列組件組成:Client,Server,Service Manager,以及Binder Driver。其中,Client,Server和Service Manager是用戶空間組件,而Binder Driver運行於內核空間。用戶層的Client和Server基於Binder Driver和Service Manager進行通訊。開發者一般無需瞭解Binder Driver與Service Manager的實現細節,只要按照規範設計實現本身的Client和Server組件便可。從Android應用程序設計的角度來看,進程通訊機制以下圖:網絡
在系統安全設計方面,Android的進程通訊機制設計具有優於傳統Linux的重要優點。架構
Android應用基於權限機制,定義進程通訊的權限,相比傳統Linux IPC具備更細粒度的權限控制。dom
Binder進程間通訊機制具有類型安全的優點。開發者在編譯應用程序時,使用Android接口接描述語言(AIDL)定義交換數據的類型,確保進程間通訊的數據不會溢出越界污染進程空間。socket
Binder經過Android的共享內存機制(Ashmem)實現高效率的進程通訊,而不是採用傳統的Linux/UNIX共享內存(Shared Memory),也具有特殊的安全含義。編程語言
Android在Binder進程通訊機制中採用Android接口描述語言(AIDL)。AIDL同傳統RPC中的IDL語言同樣,根據描述能夠生成代碼,使兩個進程經過內部通訊進程進行交互。例如,在一個Activity(一個進程)中訪問一個Service(另外一個進程)的對象/服務,使用AIDL定義接口與參數並實如今進程間的傳遞。AIDL IPC的機制是基於接口的,相似於COM與Corba,但更爲輕量級,使用代理類在客戶端和實現層間傳遞值。
AIDL的接口定義與參數描述是類型安全的,與程序設計語言中的類型安全概念一致。Android應用程序使用java語言編寫。Java語言就具有所謂的「類型安全」特性,是一種強類型化的編程語言, 它強制不一樣內容遵循規定的數據格式,進而防止錯誤或惡意應用。不完整的類型安全與邊界檢查機制極易受到內存污染或緩衝區溢出攻擊,進而致使任意代碼,甚至惡意代碼的運行。可是,在C/C++程序設計中,容許未經類型檢查的強制類型轉換,並且,除非編程者專門編程進行邊界檢查,不然C語言自己不要求邊界檢查。實踐證實,這些C/C++語言的靈活性恰成爲惡意代碼攻擊的目標。Android系統原生庫容許採用C/C++編程,存在必定的安全隱患,須要其餘特殊技術加以防範。傳統Linux的進程通訊機制雖然有用戶權限的限制,但缺乏強制的類型安全。
因爲類型安全的接口與數據描述,在接收方從其餘進程接收數據時,能夠充分檢查安全性,確保其餘進程發來的參數都在可接受的範圍內,而無論調用者想要幹什麼,均可以防止進程間通訊的數據溢出越界污染進程空間。