1. 程式人生 > >Binder學習總結_native(1)

Binder學習總結_native(1)

這幾天一直在看binder的結構,感嘆這樣天才的設計。
現在只研究到binder的native框架,在IPCThreadState以下,真正的driver和資料交換還需要進一步研究。在此記錄一些目前的體會。

1.IInterface的作用
個人感覺,這個IInterface嚴格上講,並不是Binder這個框架的一部分。
它的作用是提供了一個common的方式,可以將IBinder與Service進行顯示的轉換。
因為在進行IPC時,實際的service IXXXService要轉換成IBinder,才能傳遞給ServiceManager進行註冊檢索,或者傳遞給Client進行呼叫。
而且Client拿到ServiceManager回傳的IBinder以後,又要轉換回IXXXService進行功能呼叫,所以IInterface產生了,提供了IXXXService與IBinder互相轉換的功能。

(1)IXXXService轉換IBinder實現:
IXXXService繼承自IInterface,所以IInterface中的asBinder()方法,會將自身,也就是IXXXService轉換成一個IBinder物件。
sp<IBinder> IInterface::asBinder()
{
    return this ? onAsBinder() : NULL;
}
這個onAsBinder()是一個虛擬方法,實際上是有IInterface的兩個子類BpInterface和BnInterface實現的。
BpInterface的實現:
inline IBinder* BpInterface<INTERFACE>::onAsBinder()
{
    return remote(); //呼叫它的父類BpRefBase的remote()方法,返回IBinder,其實就是一個BpBinder
}
BnInterface的實現:
IBinder* BnInterface<INTERFACE>::onAsBinder()
{
    return this; //就是返回自身,因為BnInterface就是從BBinder繼承的,BBinder又是繼承自IBinder
}

(2)IBinder轉換IXXXService實現:
當一個Client拿到ServiceManager返回的IBinder時,需要轉換為IXXXService介面,才能呼叫它的功能。
這個轉換,是由IInterface中定義的巨集DECLARE_META_INTERFACE來宣告的asInterface完成的,並由巨集IMPLEMENT_META_INTERFACE實現的。
將巨集程式碼IMPLEMENT_META_INTERFACE展開後得到:
android::sp<IXXXService> I##INTERFACE::asInterface(                
            const android::sp<android::IBinder>& obj)                   
{                                                                   
    android::sp<IXXXService> intr;                                 
    if (obj != NULL) {                                              
        intr = static_cast<IXXXService*>(                          
            obj->queryLocalInterface( //先呼叫queryLocalInterface,這個方法是IBinder定義的,預設實現是返回NULL,而在BBinder的子類BnInterface中,過載了該方法,返回this,而
                                      //BpInterface並沒有過載,使用IBinder的預設實現,返回NULL。                             
                    IXXXService::descriptor).get());               
        if (intr == NULL)

Unknown macro: {                                                  intr = new BpXXXService(obj); //如果queryLocalInterface返回NULL,就構造一個BpXXXService返回,Client得到的正是這個BpXXXService        }

                                                           
    }                                                               
    return intr;                                                    
}
總結一下,如果傳進來的obj引數,是一個BBinder,就返回自身(這種情況應該是service和client在同一程序),如果是一個BpBinder,就new一個代理物件返回(這種情況應該是service和client在不同程序)。                                   

2.IBinder, BBinder和BpBinder
這3個類,是對Android Binder框架的抽象,其實這個BBinder,改成BnBinder可能更形象一些。
但是要注意的是,一個IXXXService的繼承圖中,BpBinder並不在這個繼承關係之中,也就是說BpBinder並沒有子類。但是BBinder是在這個繼承關係當中的,它的子類就是BnInterface。
換句話說,BBinder和BpBinder的功能並不是對稱的,以前就是沒有理解到這一點,才會一直很糊塗。

BpBinder的是存在於BpRefBase中的mRemote的成員變數中。從Client呼叫Service的過程中分析,就更清楚了。
假設有一個IXXXService介面:
class IXXXService : public IInterface {
    ....
    public void helloWorld(const char* str);
    ....
}
(1)client呼叫service
    client得到一個BpXXXService以後
    (a)會呼叫BpXXXService實現的helloWorld,它會將str引數打包到Parcel中。然後呼叫remote()->transact(xxx)
    (b)remote()是在BpXXXService的父類BpRefBase中實現的,返回的就是一個BpBinder.實際上呼叫的就是BpBinder的transact
    (c)BpBinder的transact實現,就是直接呼叫IPCThreadState::self()->transact()傳送資料。
(2)service接收client請求:
    (a)通過IPCThreadState接收到client的請求後,首先會呼叫BBinder的transact方法。
    (b)BBinder的transact方法又會呼叫子類實現的虛擬方法onTransact。這個虛擬方法是在BnXXXService中實現的。
    (c)onTransact方法,會通過傳遞進來的引數來判斷,需要呼叫IXXXService中的那個方法,示例中只有一個helloWorld方法。
    (d)直接呼叫helloWorld,就會找到它的真正實現,也就是BnXXXService的子類XXXService中的helloWorld方法。
總結一下,從上面的流程當中就可以看出前文說的,BpBinder並不在繼承關係當中,它只是一個打包資料,並通過IPCThreadState::self()->transact()方法傳送出去。
而BBinder和BnXXXService的作用,就是接收IPCThreadState傳遞過來的資訊,解包資料,並呼叫XXXService真正的實現。

IPC的資料處理,Binder Driver和ServiceManager學習後會繼續分析總結。


相關推薦

Binder學習總結_native1

這幾天一直在看binder的結構,感嘆這樣天才的設計。 現在只研究到binder的native框架,在IPCThreadState以下,真正的driver和資料交換還需要進一步研究。在此記錄一些目前的體會。 1.IInterface的作用 個人感覺,這個IInterface

《javascript 高級程序設計》學習總結1

java 關鍵字 下一個 引用 global 討論 其他瀏覽器 而後 rom    引言:任何語言的核心都必然會描述這門語言的最基本的工作原理,而描述的內容通常都要涉及這門語言的語法、操作符、數據類型、內置功能等用於構建復雜解決方案的基本概念。 今天我就這些基本的概念開始進

Python學習手冊筆記1:Python對象類型

python 在Python中一切皆對象,Python程序可以分解為模塊、語句、表達式及對象。如下所示:1 程序由模塊組成2 模塊包含語句3 語句包含表達式4 表達式建立並處理對象 內置對象(核心類型):1)數字:>>> 2+2 #整數加法4>>&g

Pro Android學習筆記 ActionBar1:Home圖標區

ces tom 新的 方便 find rac vertica lba manifest ?? Pro Android學習筆記(四八):ActionBar(1):Home圖標區 2013年03月10日 ? 綜合 ? 共 3256字 ? 字號 小 中 大 ? 評論關閉

2017-5-29學習記錄——WebApi1

ora 必須 eache 配置 person span eve gen 流行 曾經我一直認為Web服務器的Api使用ashx或ASP.NET MVC中返回JsonResult來實現的。 當我第一次接觸WCF的時候,有同學告訴我目前比較流行WebApi和WebSocket了,

bootstrap源碼學習:輔助1

div max uid 排列 lock oot 引用 flex ots .blockquote-footer::before { content: "\2014 \00A0"; } 引用的腳步~效果是插入了“—”,可以做一個署名。 .container { m

[Python接口自動化]從零開始學習python自動化1:環境搭建

help ins cnblogs 文件中 ssi 空格 plugins 變量 mod 第一步:安裝python編譯環境 安裝python編譯環境之前,必須保證已安裝jdk哈,如果為安裝,請參考https://jingyan.baidu.com/article/6dad507

FPGA小白學習之路1 System Verilog的概念以及與verilog的對比

函數返回 enable 傳遞 轉換操作符 st2 輸出 時間值 擴展 isa 轉自CSDN:http://blog.csdn.net/gtatcs/article/details/8970489 SystemVerilog語言簡介 SystemVerilog是一種硬件描

python3網絡爬蟲學習——使用requests1

返回 hub origin 存儲 python3 中文 json head flat reuqests庫中有很多便捷的方法,比如以GET方式獲得網頁,在requests庫中就是方法get(),上代碼 import requests r = requests.get(‘ht

前端學習之HTML1

HTML標籤學習 2018-10-31 記錄一下學習的網站 http://www.w3school.com.cn http://www.runoob.com/ 1 <!DOCTYPE html> 2 <html> 3 4 <head>

深度學習分割:1資料彙總

時間關係,備份一些深度學習分割演算法相關的部落格和介紹文章。 分割演算法綜述 介紹了幾個比較經典且非常重要的深度學習分割演算法。 原作地址:https://blog.csdn.net/weixin_41923961/article/details/80946586 更加全面的一篇

小李的Java學習之路1

第一天 java的面向物件思想 小葉:“為什麼要學習Java呢???” 小李:“因為Java比c語言有趣多了。。。。” 小葉:“你剛學完c語言,來說說c語言和Java的異同之處吧。” 小李:“c語言和Java的語法基礎,程式控制語句大體都是一樣的。主要是不同之處:Java和c的程

《機器學習-西瓜書》-周志華-學習筆記系列1--序言、前言和主要符號表

寫在前面的話: 自己於今天(2018年9月4日)看完了機器學習-西瓜書-周志華-清華大學出版社書籍,對於這本書的評價就是:好書,自己可以在每一個字裡行間感受到作者的用心,每當看到一個不懂的名詞的時候,作者都會用通俗的例子來講解,遇到公式的時候,也會進行推導,側邊欄的一些說明資訊往往能帶給自己

HIT機器學習期末複習1——機器學習簡介及決策樹

劉楊的機器學習終於上完了惹,下週就要考試了,趕緊複習ing...... 趁機做個總結,就當是複習了惹...... 機器學習簡介 1、什麼是機器學習 簡單來說,就是一個三元組<P, T, E> P——performance效能(對應著效能的評估函式,也就是常說的loss或者likeli

從零開始學習HTML+CSS1常用工具與網站

從零開始學習HTML+CSS(1) 開始正式學習HTML+CSS了。第一次培訓具體內容講得不多,主要介紹了一些常用工具和網站。 下面是一點整理: 工具類(個人推薦向): 瀏覽器:Google Chrome 官方下載地址:https://www.google.cn/chrome/ 編輯

Vue學習筆記重點1

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>todo-list元件版</title> <script

excel技巧總結-函式1

1、批量複製不同資料, 左邊表格為原始,右邊表格為所需要的表格。 第一步:選擇指定區域,點選Ctrl+G,選擇空值。 第二步:在選中的空值區域內填寫“=向上方向鍵” 第三步:點選Ctrl+Enter搞定上述要求 2、匹配查詢不同值 匹配查詢最好

web前端學習JavaScript學習筆記部分1-- JavaScript基礎教程

1、JavaScript基礎教程 1.1、Javascript基礎-介紹、實現、輸出 1.1.1、JavaScript是網際網路上最流行的指令碼語言,這門語言可用於web和HTML,更可廣泛用於服務端、pc端、移動端。 1.1.2、JavaScript指令碼語言   JavaScript是一種輕量級的

學習Java路程1

從大二開始接觸Java,不知不覺已經四年,大二剛開始接觸的時候,看教材上的程式碼片段就和看天書似的,懵懵懂懂,就這樣放棄了它。大三時,突然發現時間竟然過得如此之快,一尋思,整個大學生涯即將結束,說實話,內心慌了。從頭捋了一下自己所學的知識和專業技能,可悲的發現自

深度學習&PyTorch筆記 1線性迴歸模型

首先建立模型 class LinearRegression(nn.Module): def __init__(self): super(LinearRegression, self).__init__() # nn.Module 的初