1. 程式人生 > >Android - Binder機制 - ProcessState和IPCThreadState

Android - Binder機制 - ProcessState和IPCThreadState

以下幾篇文章是較深入分析binder機制。

目錄

1. Android - Binder機制 - ServiceManager

2. Android - Binder機制 - 普通service註冊

3. Android - Binder機制 - 獲得普通service

4. Android - Binder機制 - client和普通service互動

5. Android - Binder機制 - Binder框架總結

6. Android - Binder機制 - ProcessState和IPCThreadState

7. Android - Binder機制 - 驅動
Android - Binder機制 - ProcessState和IPCThreadState
IPCThreadState看上去複雜

初看IPCThreadState程式碼一頭霧水,之所以複雜,是因為IPCThreadState的程式碼一部分給客戶端使用,一部分給服務端使用,兩個一摻雜,所以就亂了。如socket程式設計,客戶端和服務端有很多一樣的操作(如開啟socket、read、write、close等),也有一些不一樣的操作(如服務端多了listen和accept,客戶端多了connect),如果我們將服務端和客戶端的程式碼寫在一起,如果你不懂socket程式設計,肯定會覺得很複雜。但是,如果我們先定義一個基類來完成服務端客戶端相同的操作,然後再建立兩個繼承類,分別執行服務端和客戶端不一樣的操作,相信這樣讓程式設計師一眼就能看出其中的關係。IPCThreadState就是因為將服務端和客戶端寫在了一起,所以顯得比較複雜。
IPCThreadState主要的函式有sendReply、waitForResponse、joinThreadPool、transact、talkWithDriver、writeTransactionData、executeCommand等。下面我們分析IPCThreadState的服務端和客戶端的流程和使用了上面哪些主要函式,你會發現這些大部分函式或者只為客戶端使用或者只為服務端使用。


服務端
Socket服務端一般要進行哪些操作呢?

初始化
開啟一個socket,bind要監聽的埠號和ip地址
變為服務端
執行listen,一個普通(預設是客戶端)的socket就變為了服務端
監聽
執行accept
接收資料
recv資料
處理資料
根據業務進行相關處理
反饋資料
Send資料
關閉
執行Close


相應的binder如何處理一個服務端呢?

初始化
開啟binder裝置,如sp<ProcessState> proc(ProcessState::self())裡執行了open_binder函式。
變為服務端
執行AddService,如CameraService::instantiate()
監聽
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
這倆其實都是起監聽的作用,binder不像socket只有一個監聽,binder可以支援很多監聽執行緒,ProcessState::self()->startThreadPool()其實也是呼叫的IPCThreadState::self()->joinThreadPool()。joinThreadPool裡迴圈呼叫talkWithDriver,該函式其實就是掃描裝置是否有資料。
接收資料
接收資料和監聽是在一起的,這裡其實很像UDP的socket程式設計,UDP是沒有accept步驟的。
反饋資料
executeCommand對各種指令進行處理,該函式會在後面詳解。
executeCommand處理的時候有些需要反饋的資料寫到mOut緩衝,那什麼時候傳送mOut的資料呢,其實還是joinThreadPool的talkWithDriver,也就是在這可以看出joinThreadPool同時幹兩個事,一個是接收資料,一個是傳送資料。
關閉
Close(mProcess->mDriverFD)


客戶端

Socket客戶端一般要進行哪些操作呢?
初始化
開啟一個socket
連線服務端
執行connect
傳送請求
send資料
接收反饋
recv資料
關閉
執行Close


相應的binder如何處理一個客戶端呢?
初始化
開啟binder裝置,如camera客戶端在哪開啟的呢,看看getCameraService函式裡面為了獲得服務,先獲得ServiceManager的函式defaultServiceManager(),該函式執行了ProcessState::self()->getContextObject(NULL),ProcessState::self()就會開啟binder裝置。
連線服務端
執行GetService,通過ServiceManager獲得了服務的Handle,以後就是靠這個Handle和服務端打交道的,就想socket的整數控制代碼。另外,客戶端業務層並不直接使用Handle,而使用了Bpxxx,它是服務端在客戶端的代理(只是為了客戶端寫程式碼更方便)。
傳送請求
執行remote()->transact,而實際是執行的IPCThreadState::transact,該函式又執行了writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL),該函式將要傳送的資料先寫入到傳送快取(mOut),又一次注意引數handle,它指定哪個服務端來處理。真正的傳送是在waitForResponse(reply)的talkWithDriver。
接收反饋

接收也是在waitForResponse(reply)的talkWithDriver函式。

talkWithDriver將需要傳送的請求buf和接收buf(即binder_write_read bwr)同時送入binder驅動,請求和傳送是一個堵塞過程(ioctrl(binder_fd, BINDER_WRITE_READ, &bwr))。
關閉
執行Close


---------------------
作者:G機器貓
來源:CSDN
原文:https://blog.csdn.net/gykimo/article/details/8901192