Binder詳解
- 1 .Linux內(nèi)核的基礎(chǔ)知識(shí)(跟Binder有關(guān)的)
- Binder通信機(jī)制介紹
- AIDL實(shí)現(xiàn)
1.Linux內(nèi)核的基礎(chǔ)知識(shí)(跟Binder有關(guān)的)
1.進(jìn)程隔離/虛擬地址空間(進(jìn)程A和進(jìn)程B的虛擬地址空間不一樣贡蓖,獨(dú)享)
2.概念:系統(tǒng)調(diào)用唯笙。進(jìn)程只可以訪問許可的資源爽锥,將Linux內(nèi)核層和上層程序抽象分離開。用戶可以通過系統(tǒng)調(diào)用港谊,在用戶空間訪問內(nèi)核的某些程序
3.binder驅(qū)動(dòng):android系統(tǒng)中夺颤,運(yùn)行在內(nèi)核空間中擅憔,負(fù)責(zé)各個(gè)用戶進(jìn)程通過binder通信的內(nèi)核進(jìn)行通信的交互模塊叫binder驅(qū)動(dòng)武氓。
驅(qū)動(dòng)程序,一般指的是設(shè)備的驅(qū)動(dòng)程序主儡,可以使計(jì)算機(jī)和設(shè)備通信的特殊程序奖唯,也是一種軟件,其實(shí)也是一種接口糜值,操作系統(tǒng)可以通過這個(gè)接口操作并控制硬件設(shè)備丰捷;
2.Binder通信機(jī)制介紹
-
1 .為什么要使用binder
- Android使用的Linux內(nèi)核擁有著非常多的跨進(jìn)程通信機(jī)制坯墨,管道,socket
- 1. 性能上:廣泛的通信機(jī)制對(duì)性能有嚴(yán)格的要求
binder相對(duì)于socket更加高效
- 2. 安全性上瓢阴,傳統(tǒng)通信對(duì)通信雙方?jīng)]有做出嚴(yán)格的驗(yàn)證畅蹂,只有上層協(xié)議才做架構(gòu),binder對(duì)通信雙方做身份校驗(yàn)荣恐,權(quán)限模型基礎(chǔ)
- Android使用的Linux內(nèi)核擁有著非常多的跨進(jìn)程通信機(jī)制坯墨,管道,socket
- binder通信模型
- 通信錄:binder驅(qū)動(dòng)液斜。
- 電話基站:serviceManager
- binder通信模型
圖1
跨進(jìn)程通信時(shí):客戶端只是持有了一個(gè)服務(wù)端的代理對(duì)象引用,具體的跨進(jìn)程通信都是通過代理對(duì)象來協(xié)助完成的
- 1 .到底什么事binder
- 1 .通常意義下叠穆,Binder指的是一種通信機(jī)制
- 2 .對(duì)于Server進(jìn)程來說少漆,Binder指的是Binder本地對(duì)象
- 1 .對(duì)Client來說,Binder指的是Binder的代理對(duì)象
- 2 .對(duì)處于同一個(gè)進(jìn)程來說硼被,客戶端Binder也是本地對(duì)象
- 3 . 客戶端對(duì)象和服務(wù)端對(duì)象是無法交互的示损,只有使用binder通過ServiceManager才能交互
- 3 .對(duì)于傳輸過程而言,Binder是可以進(jìn)行跨進(jìn)程傳遞的對(duì)象
- binder驅(qū)動(dòng)會(huì)對(duì)具有跨進(jìn)程傳入能力的對(duì)象(不是嚷硫。检访。繼承了PacexxBle,沒搞清)做特殊處理仔掸,自動(dòng)會(huì)完成對(duì)代理對(duì)象和服務(wù)端對(duì)象的轉(zhuǎn)換
- 3 . binder通信機(jī)制原理
3.AIDL實(shí)現(xiàn)(Binder的實(shí)例)
圖2
圖3
圖4
圖5
圖6
圖7
圖8
圖9
生成一個(gè)靜態(tài)Stub類脆贵,繼承android.os.Binder,實(shí)現(xiàn)本地定義的AIDL接口
- 說明是一個(gè)Binder本地對(duì)象,具有遠(yuǎn)程服務(wù)端承諾給客戶端遠(yuǎn)程傳遞數(shù)據(jù)的能力起暮。
- 又由于Stub這個(gè)抽象類是個(gè)抽象的卖氨,具體的實(shí)現(xiàn)需要自己來。這個(gè)是java中的一個(gè)策略模式负懦。
- 首先asInterface(android.os.IBinder obj):這是一個(gè)接口筒捺,代表了跨進(jìn)程傳輸?shù)哪芰Γ灰獙?shí)現(xiàn)了這個(gè)接口就能將這個(gè)對(duì)象跨進(jìn)程傳遞纸厉,驅(qū)動(dòng)底層支持的系吭,驅(qū)動(dòng)會(huì)識(shí)別支持IBinder類型的數(shù)據(jù)
其中:
public static 自定義的AIDL接口名稱 asInterface(android.os.IBinder obj){
if(obj == null){return null;}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPOR);
if(((iin!=null)&&)(iin instanceof 自定義的AIDL接口名稱))){
return ((自定義的AIDL接口名稱)iin)
}
return new 自定義的接口名稱.Stub.Proxy(obj);
}
//如果是同一個(gè)進(jìn)程的話就使用iin,如果不是同一個(gè)進(jìn)程的話就會(huì)使用使用它的代理對(duì)象
在這個(gè)Stub類中颗品,實(shí)現(xiàn)了compute方法
public int compute(int a,int b)throw android.os.RemoteException{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try{
_data.writeInterfaceToken(DESCRIPTIOR);
_data.writeInt(a);
_data.write(b);
mRemote.transat(Stub.TRANSACTION_compute,_data,_reply,0);
_reply.readExcption();
_result = _reply.readInt();
}
finally{
_reply.recycle();
_data_recycle();
}
return _result;
}
IBinder類中:
public boolean transact(int code,Parcel data,Prarcel reply,int flags) throw RemoteException;
其實(shí)是一個(gè)native層的方法肯尺,最終會(huì)調(diào)用到onTransat方法
看Stub實(shí)現(xiàn)
根據(jù)調(diào)用號(hào),調(diào)用剛才寫的compute跨進(jìn)程調(diào)用方法
public boolean onTransact(int code,android.os.Parcel data,android.os.Parcel reply,int flags)throw android.os.xxException{
switch(code){
case INTERFACE_TRANSACTION:{
reply.writeString(DESCRIPTOR);
}
case TREANSACTION_compute:{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.compute(_arg0,_arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code,data,reply,flags);
}
- 先用Parcel將數(shù)據(jù)序列化
- 然后調(diào)用transact方法抛猫,最終會(huì)調(diào)用的onTransat方法蟆盹,然后根據(jù)調(diào)用號(hào)孩灯,調(diào)用到compute 自定義的AIDL方法