很多BAT也不一定能懂的binder機(jī)制! 分4篇文字講解: 01. Android Binder圖解 小米系統(tǒng)專家 解析Service 的addService注冊(cè)過程 (安卓12) 02. Android Binder圖解 小米系統(tǒng)專家 解析 ServiceManager和binder通信 (安卓12) 03. Android Binder圖解 小米系統(tǒng)專家 解析binder驅(qū)動(dòng)層解析binder通信過程 (安卓12) 04. Android Binder圖解 小米系統(tǒng)專家 從binder java層解析binder整個(gè)流程(安卓12) binder包含4部分:我將Binder機(jī)制分為了Java Binder、Native Binder、Kernel Binder, 一句話總結(jié):把service服務(wù)通過binder驅(qū)動(dòng)添加到serverManager的過程 系統(tǒng)源碼位置: /frameworks/av/media/mediaserver/main_mediaserver.cpp 一. MediaPlayerService是怎么創(chuàng)建的 media進(jìn)程是init進(jìn)程解析init.rc開啟的 Media 進(jìn)程是由init 進(jìn)程通過解析 init.rc 文件而創(chuàng)建的。 service media /system/bin/mediaserver 二:我們先來看MediaServer的入口函數(shù),代碼如下所示。 int main(int argc __unused, char argv __unused) { signal(SIGPIPE, SIG_IGN); 打開binder驅(qū)動(dòng) 三. 添加defaultServiceManager() frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp void MediaPlayerService::instantiate() { 四:傳遞數(shù)據(jù) frameworks/native/libs/binder/IServiceManager.cpp 然后傳給BpBinder的transact函數(shù),代碼如下所示。 BpBinder類通過IPCThreadState類來與Binder驅(qū)動(dòng)交互 BpBinder將邏輯處理交給IPCThreadState IPCThreadState的transact函數(shù)。 在內(nèi)存中創(chuàng)建一個(gè)Binder節(jié)點(diǎn),將自己置為0號(hào)節(jié)點(diǎn),這里的handle 值為 0 代表是 ServiceManager 進(jìn)程
frameworks/native/libs/binder/IPCThreadState.cpp *``` } **總結(jié): 1.addService函數(shù)將數(shù)據(jù)打包發(fā)送給BpBinder來進(jìn)行處理。 2.BpBinder新建一個(gè)IPCThreadState對(duì)象,并將通信的任務(wù)交給IPCThreadState。 3.IPCThreadState的writeTransactionData函數(shù)用于將命令協(xié)議和數(shù)據(jù)寫入到mOut中。 4.IPCThreadState的waitForResponse函數(shù)主要做了兩件事,一件事是通過ioctl函數(shù)操作mOut和mIn來與Binder驅(qū)動(dòng)進(jìn)行數(shù)據(jù)交互,另一件事是處理各種命令協(xié)議。** **open 是打開驅(qū)動(dòng)、mmap 是映射驅(qū)動(dòng)、ioctl 是操作驅(qū)動(dòng)、close 是關(guān)閉驅(qū)動(dòng), 分別對(duì)應(yīng)驅(qū)動(dòng)層的 binder_open、binder_mmap、binder_ioctl 和 binder_colse 方法 最終通過ioctl函數(shù)和Binder驅(qū)動(dòng)進(jìn)行通信,最后是交給了binder 驅(qū)動(dòng)的 ioctl 方法,這一部分涉及到Kernel Binder的內(nèi)容** 面試常問的問題: 問題:請(qǐng)問****MediaPlayerService****所在的進(jìn)程,如何和binder驅(qū)動(dòng)通信的?(重點(diǎn)) MediaPlayerService是如何注冊(cè)的。通過了解MediaPlayerService是如何注冊(cè)的,可以得知系統(tǒng)服務(wù)的注冊(cè)過程 我的理解: 1).打開binder驅(qū)動(dòng) 2). 把對(duì)應(yīng)的參數(shù),封裝成bpbinder序列化的對(duì)象,交給binder驅(qū)動(dòng) 打開/dev/binder設(shè)備,這樣的話就相當(dāng)于和內(nèi)核binder機(jī)制有了交互的通道 l 映射fd到內(nèi)存,設(shè)備的fd傳進(jìn)去后,估計(jì)這塊內(nèi)存是和binder設(shè)備共享的 binder_ioctl() 問題:MediaPlayerService和servermanager是不同進(jìn)程,如何通信的? 通過binder驅(qū)動(dòng)。內(nèi)核,內(nèi)存映射關(guān)系。 問題:bpbinder有什么作用? Bn 是Binder Native的含義,是和Bp相對(duì)的,Bp的p是proxy代理的意思,那么另一端一定有一個(gè)和代理打交道的東西,這個(gè)就是Bn。 講到這里會(huì)有點(diǎn)亂喔。先分析下,到目前為止都構(gòu)造出來了什么。 l BpServiceManager l BnMediaPlayerService 數(shù)據(jù)流向: 具體的數(shù)據(jù)有 interfaceToken(遠(yuǎn)程服務(wù)的名稱)、handle(遠(yuǎn)程服務(wù)的句柄)、cookie(本地服務(wù)的地址), 有兩個(gè)結(jié)構(gòu)體 flat_binder_object 和 binder_write_read。 問題:Media 服務(wù)是如何添加到servermanager中的? 1).Media 進(jìn)程是由 init 進(jìn)程通過解析 init.rc 文件而創(chuàng)建的。 2). 最后是交給了binder 驅(qū)動(dòng)的 ioctl 方法 問題:binder進(jìn)程是在哪里啟動(dòng)的? 我們知道Zygote進(jìn)程會(huì)調(diào)用AndroidRuntime::startReg函數(shù)注冊(cè)一系列的JNI函數(shù),而這其中就包括我們的Android Framework層的Binder框架層相關(guān)的JNI,此時(shí)就標(biāo)志著Framework層BInder框架的啟動(dòng),而不是到了system_server進(jìn)程才開始啟動(dòng)的! 作者:鵬城十八少 鏈接:https://www.jianshu.com/p/807da3708055 |
|