android 進程間通訊---bind的前世

在分析bind機制以前,我發現已經有一篇文章講解的很是清晰,而且提出了不少問題。java

地址:http://my.oschina.net/keeponmoving/blog/64218linux

 

一.Linux系統進程間通訊有哪些方式?
    1.socket; 2.name pipe命名管道; 3.message queue消息隊列; 4.singal信號量; 5.share memory共享內存;
二.Java系統的通訊方式是什麼? 1.socket; 2.name pipe;
三.Android系統通訊方式是什麼? Binder 通訊;
四.Binder通訊的優點是什麼? 高效率
五.Binder通訊的特色是什麼? 是同步,而不是異步;
六.Binder通訊是如何實現的?
   1.Binder通訊是經過linux的binder driver來實現的,
   2.Binder通訊操做相似線程遷移(thread migration),兩個進程間IPC看起來就象是一個進程進入另外一個進程執行代碼而後帶着執行的結果返回;
   3.Binder的用戶空間爲每個進程維護着一個可用的線程池,線程池用於處理到來的IPC以及執行進程本地消息,Binder通訊是同步而不是異步。
七. Android中的 Binder通訊實現要點:
   1. Android中的Binder通訊是基於Service與Client的工做模型的;
   2. 全部須要IBinder通訊的進程都必須建立一個IBinder接口;
   3. 系統中有一個進程管理全部的system service:
   4. Android不容許用戶添加非受權的System service;
   5. 如今源碼開放了,咱們能夠修改一些代碼來實現添加底層system Service的目的;
   6. 對用戶程序來講,咱們也要建立server,或者Service用於進程間通訊;
   7. ActivityManagerService管理JAVA應用層全部的service建立與鏈接(connect),disconnect;
   8. 全部的Activity也是經過這個service來啓動,加載的;
   9. ActivityManagerService也是加載在Systems Servcie中的;
八.Android的 Service工做流程
  1.Android虛擬機啓動以前系統會先啓動service Manager進程;
  2.service Manager打開binder驅動,並通知binder kernel驅動程序這個進程將做爲System Service Manager;
  3.而後該進程將進入一個循環,等待處理來自其餘進程的數據。
  4.用戶建立一個System service後,經過defaultServiceManager獲得一個遠程ServiceManager的接口,經過這個接口咱們能夠調用addService函數將System service添加到Service Manager進程中;
  5.而後client能夠經過getService獲取到須要鏈接的目的Service的IBinder對象,這個IBinder是Service的BBinder在binder kernel的一個參考,
  6.因此service IBinder 在binder kernel中不會存在相同的兩個IBinder對象,每個Client進程一樣須要打開Binder驅動程序。對用戶程序而言,咱們得到這個對象就能夠經過binder kernel訪問service對象中的方法。
  7.Client與Service在不一樣的進程中,經過這種方式實現了相似線程間的遷移的通訊方式,對用戶程序而言當調用Service返回的IBinder接口後,訪問Service中的方法就如同調用本身的函數。
 

以下是詳細說明Binder。android

 

1. binder的結構數據結構

  binder是解決ipc和rpc的工具。android使用的是linux os,支持多進程和多線程。同時,對於java app,一個vm佔用一個進程。作爲完善的開發框架,android必須支持ipc。binder就是解決ipc問題的途徑,更進一步,binde還支持rpc。多線程

  進程有本身的地址空間,不一樣進程間的通訊並不能直接引用地址。通常的解決途徑是,發送進程把須要傳送的數據按照必定格式(marshall)轉換成二進制形式/特定格式的數據,發往接收進程;接收進程收到二進制形式、特定格式的數據後,反轉換(unmarshall)成原文數據,而後使用。binder使用的就是這種步驟。架構

  binder使用的是同步c/s模型,s循環阻塞在接收數據操做上,隨時處理c的數據,處理後發送回c;c則將請求服務的數據發送到s,阻塞在收取s返回數據,收到數據後,繼續本身的工做。app

  binder的框架能夠分紅3層,框架

  最下層是linux os和binder driver。binder driver本質上是進程間的共享內存,各進程將要發送到其它進程的數據寫入到driver,從driver讀取其它進程發送來的數據。異步

  中間層是cpp實現的framework,完成數據的接收發送轉換,和c/s流程的支持。socket

  其實到中間層,binder的架構就已經徹底具有了。但android使用的是java作爲通常app的開發語言。因此還須要jni和相應java binder類的支持,這就是中間層上面的第三層:jni/java

  假設c,s都是java實現,app ipc通常的情景是這樣的, app client 收集ipc的數據,穿過jni,加工下傳,經framework,寫入driver。數據經driver上傳,反加工經framework,穿過jni,上傳到app server。

  對於rpc的支持,須要一點點技巧,直接傳遞函數指針是沒法使用的。爲了是敘述的方便,先澄清一對概念:本地local和遠端remote。定義rpc函數的進程稱做本地,調用rpc函數的進程稱做遠端。rpc的實現其實是遠端定義一個rpc的proxy,遠端將proxy想作rpc在本地的實現,貌似本地函數操做通常使用。而這個proxy實際上僅僅是將本身登記在本地的handle和入口參數發送本地,本地根據handle,知曉是哪一個遠端進程的proxy,調用函數,給定入口參數,執行完畢後,將出口參數再返回遠端的proxy(由於咱們有handle了)。binder的實現中handle和本地函數的對應關係是保存在driver中管理的。

2. binder driver

  binder driver是binder機制的基礎,是實現ipc的通道。

  binder driver與framework和app的功能操做是用ioctl方式實現的。最基本的操做是數據讀寫操做。一次讀寫操做有兩個子操做組成:寫子操做和讀子操做。driver爲每一個進程和線程維護了一個數據結構,其中有一個list,掛接了其它進程寫入的數據,還有一個信號量。寫子操做負責將數據掛接到接收進程對應數據結構的list上。讀子操做負責處理本身進程中list上的數據,傳回framework和app。

  binder driver的第二個功能是爲了支持rpc,就是維護本地函數和遠端proxy的handle之間的對應關係。更復雜的是維護兩個遠端Proxy的handle之間的對應關係,這兩個proxy是同一rpc的proxy。

3. binder framework

  binder的framework是cpp實現的,這裏分紅本地local/s和遠端remote/c兩半來描述。  公共類IBinder派生出兩個子類,BBinder用於local,BpBinder用於remote。  本地實現的類以BBinder爲基類派生,接收數據後,處理,並將結構發會遠端。  遠端proxy的類使用BpBinder,接收和發送數據到本地。  進一步方便開發,引入了IInterface類,開發者從Interface派生子類,定義本身須要的rpc操做。

  在IInterface的裝飾下,從BBinder派生出了本地的關鍵類 BnInterface<INTERFACE>;從BpRefBase派生出了包含成員BpBinder對象的遠端關鍵類BpInterface<INTERFACE>。

  因而,創世紀中,神說:‘要有光’,就有了光。神看光是好的,就把光暗分開了。 神稱光爲晝,稱暗爲夜。有晚上,有早晨,這是頭一日。

4. binder jni,java類和aidl工具

  binder framework的機制要被java使用,須要通過包裝。除了jni相關部分,android在java中還定義了幾個相關的接口和類,IBinder,Binder,BinderProxy,IInterface,BinderInternal。

  aidl工具則是方便java實現c/s結構的一個工具,開發者編寫簡單的接口描述idl文件,則aidl自動生成local和remote的Binder類。讓開發者關注在實際的功能開發上,沒必要爲binder機制耗費無謂的精力。

5. parcel是什麼

  爲了便於ipc之間傳遞的數據的操做,binder引入了parcel的概念。parcel能夠想成快遞公司的包裝箱,須要傳遞的各類類型的數據都被打包進parcel類,binder負責傳遞parcel對象,接收端則從parcel解出數據。這樣的機制即減小了各類數據類型對傳遞的複雜性,又能夠經過增長打包/解包parcel的數據類型,輕易實現擴展。

  parcel已經支持容納基本數據類型和一些複合數據類型。  在framework層面,parcel提供了Flattenable基類,能夠擴展parcel容納的數據類型。  在java parcel層面,parcel提供了Parcelable接口,能夠擴展parcel容納的數據類型。

6. 依賴於binder的service

  ipc/rpc已經被binder機制解決掉了,那麼service面臨的惟一問題就是service如何讓想使用service的client招到service。解決的方案就是 service manager。service manager是一個特殊進程,每一個service都會註冊登記到service manager中,而client能夠從service manager查詢獲得本身須要使用的service。

相關文章
相關標籤/搜索