Binder详解
- 1 .Linux内核的基础知识(跟Binder有关的)
- Binder通信机制介绍
- AIDL实现
1.Linux内核的基础知识(跟Binder有关的)
1.进程隔离/虚拟地址空间(进程A和进程B的虚拟地址空间不一样,独享)
2.概念:系统调用。进程只可以访问许可的资源,将Linux内核层和上层程序抽象分离开。用户可以通过系统调用,在用户空间访问内核的某些程序
3.binder驱动:android系统中,运行在内核空间中,负责各个用户进程通过binder通信的内核进行通信的交互模块叫binder驱动。
驱动程序,一般指的是设备的驱动程序,可以使计算机和设备通信的特殊程序,也是一种软件,其实也是一种接口,操作系统可以通过这个接口操作并控制硬件设备;
2.Binder通信机制介绍
-
1 .为什么要使用binder
- Android使用的Linux内核拥有着非常多的跨进程通信机制,管道,socket
- 1. 性能上:广泛的通信机制对性能有严格的要求
binder相对于socket更加高效
- 2. 安全性上,传统通信对通信双方没有做出严格的验证,只有上层协议才做架构,binder对通信双方做身份校验,权限模型基础
- Android使用的Linux内核拥有着非常多的跨进程通信机制,管道,socket
- binder通信模型
- 通信录:binder驱动。
- 电话基站:serviceManager
- binder通信模型
跨进程通信时:客户端只是持有了一个服务端的代理对象引用,具体的跨进程通信都是通过代理对象来协助完成的
- 1 .到底什么事binder
- 1 .通常意义下,Binder指的是一种通信机制
- 2 .对于Server进程来说,Binder指的是Binder本地对象
- 1 .对Client来说,Binder指的是Binder的代理对象
- 2 .对处于同一个进程来说,客户端Binder也是本地对象
- 3 . 客户端对象和服务端对象是无法交互的,只有使用binder通过ServiceManager才能交互
- 3 .对于传输过程而言,Binder是可以进行跨进程传递的对象
- binder驱动会对具有跨进程传入能力的对象(不是。。继承了PacexxBle,没搞清)做特殊处理,自动会完成对代理对象和服务端对象的转换
- 3 . binder通信机制原理
3.AIDL实现(Binder的实例)
图2图3 图4 图5 图6 图7 图8 图9
生成一个静态Stub类,继承android.os.Binder,实现本地定义的AIDL接口
- 说明是一个Binder本地对象,具有远程服务端承诺给客户端远程传递数据的能力。
- 又由于Stub这个抽象类是个抽象的,具体的实现需要自己来。这个是java中的一个策略模式。
- 首先asInterface(android.os.IBinder obj):这是一个接口,代表了跨进程传输的能力,只要实现了这个接口就能将这个对象跨进程传递,驱动底层支持的,驱动会识别支持IBinder类型的数据
其中:
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);
}
//如果是同一个进程的话就使用iin,如果不是同一个进程的话就会使用使用它的代理对象
在这个Stub类中,实现了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;
其实是一个native层的方法,最终会调用到onTransat方法
看Stub实现
根据调用号,调用刚才写的compute跨进程调用方法
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将数据序列化
- 然后调用transact方法,最终会调用的onTransat方法,然后根据调用号,调用到compute 自定义的AIDL方法
网友评论