Binder進程間通信系統

Binder進程間通信系統


Android應用程序由Activity、Service、BroadcastReceiver、ContentProvider四種類型組件構成,它們可能運行在同一進程中,也可能運行在不同進程中,此外各種系統組件也運行在獨立的進程中,例如,Activity管理服務AMS和PMS都運行在系統進程System進程中,那麼,這些運行在不同進程中的應用程序和系統組件是如何通信的呢?


Android基於Linux內核開發,Linux提供的進程間通信:

  • 管道(Pipe)
  • 信號(Signal)
  • 消息隊列(MessageQunue)
  • 共享內存(ShareMemory)
  • 套接字(Socket)

Android 進程間通信 – Binder

Binder進程通信機制採用CS通信方式;

提供服務的進程 -> Server進程(可同時運行多個Service組件向Client進程提供服務)
訪問服務的進程 -> Client進程(可同時向多個Service組件請求服務,每個請求對應一個Client組件或者稱爲Service代理對象)

每一個Server進程和Client進程都維護一個Binder線程池來處理進程間通信請求

Server進程和Client進程依靠內核空間的binder驅動程序(設備文件/dev/binder)

Service組件啓動時,會將自己註冊到ServiceManager組件中以便Client組件可以通過ServiceManager組件找到它

ServiceManager組件稱爲Binder進程間通信的上下文管理者,由於它也需要和Service進程、Client進程通信,可將它看做一個特殊的Service組件。
  • Service組件實現原理
    這裏寫圖片描述
  • Client組件實現原理
    這裏寫圖片描述

Binder進程間通信機制涉及了Client、Service、ServiceManager、Binder四個角色;

這裏寫圖片描述

Binder進程間通信機制的四個使用情景:

  • ServiceManager的啓動過程
  • ServiceManager代理對象的獲取過程
  • Service組件的啓動過程
  • Service代理對象的獲取過程

  • ServiceManager的啓動過程

    ServiceManager 是由init進程負責啓動的,而init進程是在系統啓動時啓動的,腳本如下:
    這裏寫圖片描述
    ServiceManager對應的程序文件servicemanager,源代碼目錄價結構:
    這裏寫圖片描述
    main函數入口在service_manager.c中:
    這裏寫圖片描述

    ServiceManager的啓動過程由三個步驟組成:

    • 調用函數binder_open打開設備文件/dev/binder,以及將它映射到本進程的地址空間
    • 調用函數binder_become_context_manager將自己註冊爲Binder進程通信機制的上下文管理者
    • 調用函數binder_loop來循環等待和處理Client進程的通信請求

  • ServiceManager代理對象的獲取過程

    ServiceManager代理對象的關係圖
    這裏寫圖片描述
    由於ServiceManager的句柄值恆爲0,因此獲取它的代理對象的過程省去了與binder驅動程序交互的過程
    Android系統在應用程序框架層的Binder庫中提供了一個函數defaultServiceManager來獲得一個ServiceManager代理對象
    這裏寫圖片描述

有了ServiceManager代理對象,Service組件就可以在啓動過程中使用它的函數addService將自己註冊到ServiceManager中,Client組件就可以使用它的函數getService來獲得一個指定名稱的Service組件的代理對象。


  • Service組件的啓動過程

    Servie組件是在Server進程中運行,Service進程在啓動時,會首先將它裏面的Service組件註冊到ServiceManager中,接着再啓動一個Binder線程池來等待和處理Client組件的通信請求。

    Service組件FregService是運行在FregServer進程中的
    這裏寫圖片描述
    註冊Service組件
    這裏寫圖片描述
    實際調用了BpServiceManager類的addServcie函數
    這裏寫圖片描述

Client進程和Server進程的一次進程間通信可劃分5個步驟:

  • Client進程將進程間通信數據封裝成一個Parcel對象,以便可以將進程間通信數據傳遞給Binder驅動程序.
  • Client進程向Binder驅動程序發送一個BC_TRANSACTION命令協議,Binder驅動程序根據協議內容找到目標Server進程之後,就會向Client進程發送一個BR_TRANSACTION_COMPLETE返回協議,表示它的進程間通信請求已經接受。Client進程接收到Binder驅動程序發送給它的BR_TRANSACTION_COMPLETE返回協議,並且對它進行處理之後,就會再次進入到 Binder驅動程序中等待目標Server進程返回進程通信結果。
  • Binder驅動程序在向Client進程發送BR_TRANSACTION_COMPLETE返回協議的同時,也會向目標Server進程發送一個BR_TRANSACTION返回協議,請求目標Server進程處理該進程間通信請求。
  • Server進程接收到Binder驅動程序發來的BR_TRANSACTION返回協議,並且對它進行處理之後,就會向Binder驅動程序發送一個BC_REPLY命令協議,Binder驅動程序根據協議內容找到目標Client進程之後,就會向Server進程發送一個BR_TRANSACTION_COMLETE返回協議,表示它返回的進程間通信結果已經收到了,Server進程接收到Binder驅動程序發送給它的BR_TRANSACTION_COMPLETE返回協議,並且對它進行處理之後,一次進程通信過程就結束了,接着它會再次進入到Binder驅動程序中等待下一次進程間通信請求。
  • Binder驅動程序向Server進程發送BR_TRANSACTION_COMPLETE返回協議的同時,也會向目標Client進程發送一個BR_REPLY返回協議,表示Server進程已經處理完成它的進程間通信請求了。並且將進程間通信結果返回給它。
Client進程和Server進程其實並不需要對BR_TRANSACTION_COMPLETE返回協議做特殊處理,這樣做是爲了讓Client進程和Server進程在執行通信的過程中,有機會返回到用戶空間去做其他事情,從而增加他們的併發處理能力。

  • Service代理對象的獲取過程
    FregClient進程獲得運行在FregServer進程中的Service組件FregService的代理對象。
    這裏寫圖片描述
    ServiceManager代理對象函數getService的實現
    這裏寫圖片描述
    調用函數checkService來獲得一個名稱爲name的Service組件的代理對象。
    這裏寫圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章