關于匿名binder的傳輸原理總結。

一绊含、緣由

網上有很多關于AIDL原理的講述,但一直有個疑問是binder為什么在service端是stub炊汹,而客戶端拿到就變成BinerProxy躬充?網上講了很多,但一到這個地方就一筆帶過讨便,所以決定自己研究下充甚。

二、首先簡述下AIDL使用流程

1.創(chuàng)建AIDL文件

AIDL文件會在build下生成java文件霸褒。如下:

在service中創(chuàng)建binder伴找,實現stub并在service的onBind()中返回如下:

在另一個進程中綁定

單步調試看下傳過來的binder


可以看到客戶端是BinderProxy類型。

三废菱、分析service綁定流程尋找stub在何處被轉化成了binderProxy

要找到從哪里轉化必須分析service綁定流程技矮,

從bindService函數起

ContextWrapper.java中

我們知道是裝飾模式,實現在ContextImpl.java中

調用bindServiceCommon函數

可以看到這個ActivityManagerNative.getDefault().bindService殊轴,通過代理實際上調用了ActivityManagerService.java的bindService函數

繼續(xù)bindServiceLocked函數衰倦,太長截取關鍵代碼

調用了bringUpServiceLocked函數,繼續(xù)

調用了realStartServiceLodcked函數


調用了scheduleCreateService和requestServiceBindingsLocked旁理,猜想這兩個函數就是創(chuàng)建service和bindservice樊零,成功后肯定回調service的onCreate和onBind。

此處又用到了代理孽文,實際上實現函數在ActivityThread.java中驻襟,我關心的是onBind回調,所以直接看scheduleBindService這個函數


又用了個message芋哭,繼續(xù)


終于找到了沉衣,通過調用service的onBind函數拿到了Binder,此時binder還是stub類楷掉。緊接著通過代理調用了ActivityManagerService的publishService函數厢蒜,看到binder是直接作為參數傳進去的霞势。

參數繼續(xù)傳,繼續(xù)跟蹤

binder沒做處理斑鸦,直接回調了c.conn.connected愕贡。在一開始ContextImpl.java的bindServiceCommon函數中做了一些準備工作,就是創(chuàng)建這個回調類巷屿。此處調用到了

繼續(xù)

繼續(xù)

在doConnected中調用了ServiceConnection類的onServiceConnected函數固以,就是我們在客戶端寫的綁定回調。流程結束嘱巾,不過問題沒解決憨琳,參數binder始終沒變,哪里搗鬼旬昭?

從handleBindService拿到binder開始起篙螟,此時還是服務端service進程,和ActivityManagerService交互问拘,將binder交給了ActivityManagerService,ActivityManagerService又交給客戶端回調onServiceConnected遍略。

剛才分析時遇到ActivityManagerNative.getDefault(),由于也是binder通信骤坐,直接找到了實現ActivityManagerService進行分析绪杏。

這里有兩點:

1.我們寫的service和ActivityManagerService通過binder進行傳輸。

2.傳輸時的又有一個binder作為參數纽绍。這個binder是我們寫的service和client通信用的binder蕾久。

重新分析下ActivityManagerNative.getDefault().publishService( data.token, data.intent, binder);

在ActivityManagerNative定義了Proxy端操作

Parcel類型,通過writeStrongBinder將binder寫入拌夏,分析Parcel.java

private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);

調到了jni了僧著,在android_os_Parcel.cpp中

ibinderForJavaObject將binder轉化為C++層對應得binder,也就是JavaBBinderHolder障簿,JavaBBinderHolder是個裝飾類霹抛,里面有JavaBBinder,而JavaBBinder繼承BBinder卷谈。最后通過Parcel.java中的writeStrongBinder寫入到binder驅動中杯拐。

writeStrongBinder調用flatten_binder

flatten_binder區(qū)分了情況本地binder將type置為BINDER_TYPE_BINDER

我們當然在研究跨進程的binder,所以此處置為BINDER_TYPE_HANDLE世蔗,并創(chuàng)建了BpBinder類端逼。BpBinder就是BinderProxy在C++層的對應類。分析到此處大致明白污淋,讀取binder的時候肯定是找到BpBinder顶滩,進而找到BinderProxy,返回給了ActivityManagerService寸爆。

看下怎們讀取的

看ActivityManagerService如何拿到傳過來的binder礁鲁,類似

通過readStrongBinder拿到binder盐欺,然后調用了publishService()函數給客戶端〗龃迹看jni對應的函數

此處終于明白了冗美,parcel->readStrongBinder()找到BpBinder,javaObjectForIBinder()返回對應的BinderProxy給ActivityManagerService析二。

如下

之前寫的時候置位了粉洼,是BINDER_TYPE_HANDLE

在getStrongProxyForHandle中判斷BpBinder是否存在,直接找到或創(chuàng)建并返回叶摄。

再看javaObjectForIBinder()

通過對應關系找到BinderProxy属韧,如果找不到就創(chuàng)建BinderProxy,并將BinderProxy和BpBinder建立對應關系蛤吓。gBinderProxyOffsets即jni調用java的BinderProxy類宵喂。如下

所以在ActivityManagerService拿到binder的時候,這個binder已經是BinderProxy会傲,后面給到客戶端回調onServiceConnected函數樊破。

分析完畢。

四唆铐,小結

一開始有這個疑問還是由于對binder的結構了解不深入”蓟總結兩點艾岂。

(1)Binder分為java層Binder和C++層Binder。Android代碼中使用binder的方式很靈活朋其,可以不關心C++層層Binder王浴,直接通過java層Binder封裝使用,即本例討論的AIDL方式梅猿∶ダ保可以在C++直接創(chuàng)建BBbinder和BpBinder來進行通信,比如深入理解android中講到的MediaServer袱蚓。當然也可以一側使用java钞啸,另一側使用C。更直接的可能直接通過ioctl方式直接寫入binder驅動都可能喇潘。不了解binder的結構就發(fā)現各種資料講解的都不一樣体斩,其實只是這幾種使用方式的排列組合。只要了解一點颖低,BinderProxy對應BpBinder絮吵,Binder對應BBinder的關系就不會錯。

(2)系統(tǒng)service都在SystemServer進行注冊忱屑,系統(tǒng)service的binder都是通過SystemServer查找拿到蹬敲。SystemServer負責返回給客戶端代理對象即BinderProxy暇昂。匿名binder,即本例討論的AIDL伴嗡,在和ActivityManagerService傳輸的過程中進行轉化急波。binder作為對象被傳輸,具體就是通過writeStrongBinder和readStrongBinder闹究。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末幔崖,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子渣淤,更是在濱河造成了極大的恐慌赏寇,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件价认,死亡現場離奇詭異嗅定,居然都是意外死亡,警方通過查閱死者的電腦和手機用踩,發(fā)現死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門渠退,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人脐彩,你說我怎么就攤上這事碎乃。” “怎么了惠奸?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵梅誓,是天一觀的道長。 經常有香客問我佛南,道長梗掰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任嗅回,我火速辦了婚禮及穗,結果婚禮上,老公的妹妹穿的比我還像新娘绵载。我一直安慰自己埂陆,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布娃豹。 她就那樣靜靜地躺著猜惋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪培愁。 梳的紋絲不亂的頭發(fā)上著摔,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音定续,去河邊找鬼谍咆。 笑死禾锤,一個胖子當著我的面吹牛,可吹牛的內容都是我干的摹察。 我是一名探鬼主播恩掷,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼供嚎!你這毒婦竟也來了黄娘?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤克滴,失蹤者是張志新(化名)和其女友劉穎逼争,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體劝赔,經...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡誓焦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了着帽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杂伟。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仍翰,靈堂內的尸體忽然破棺而出赫粥,到底是詐尸還是另有隱情,我是刑警寧澤予借,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布越平,位于F島的核電站,受9級特大地震影響蕾羊,放射性物質發(fā)生泄漏。R本人自食惡果不足惜帽驯,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一龟再、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尼变,春花似錦利凑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至度气,卻和暖如春割按,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背磷籍。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工适荣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留现柠,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓弛矛,卻偏偏與公主長得像够吩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子丈氓,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容