xiewenfeng / test Goto Github PK
View Code? Open in Web Editor NEWandroid学习笔记
android学习笔记
传统的Linux进么IPC通信机制有:pipe/signal/trace/管道/共享内存/消息队列/Socket,Android中使用Binder通信的原因有以下几点:
(1) C/S通信
采用C/S通信模式的,只有Socket支持C/S,但socket是一个通用接口,传输效率低;
(2) 传输效率高
相比于管理和消息队列等采用存储转发方式,需要拷贝2次数据,效率低;而共享内存传输过程中不需要数据拷贝,但控制机制复杂,想在IPC通信时,获取对方进程pid,需要多种机制协同操作。Binder机制只需要拷贝数据一次,效率高;
(3) 安全性高
Linux的IPC机制,没有采取一些安全措施,得依赖上层协议来进行安全控制,而Binder机制在内核空间添加身份标识UID/PID,安全性高;且Binder可以建立私有通道。
匿名Binder就是建立私有点对点通道,在Binder通信中,不需注册给SM广而告之,Server可以通过已建立的实体Binder连接将创建的Binder实体传给Client。
Binder框架定义了四个角色:Client, Server, ServiceManager, Binder驱动,其中Client, Server, ServiceManager位于用户空间,Binder驱动在内核空间,ServiceManager作为守户进程,处理所有客户端请求,管理所有服务项。
具体通信过程如下:
(1)Server在自己进程中创建服务的Binder实体,并将Binder实体和名字打包传给Binder驱动;
(2)Binder驱动为服务建立位于内核空间的Binder实体节点及Binder引用;
(3)Binder驱动将Binder名字及Binder引用打包传给ServiceManager,通知SM注册名XX的服务;
(4)SM收到数据包后,取出服务名字及Binder引用,填入查找表;
(5)当Client向SM发起服务查询请求,SM在查找表中找到该Service的Binder引用,并把Binder引用传给Client;
(6)Client通过Binder引用调用Server端函数。
这四种角色的作用:
Binder对象是一个可以跨进程引用的对象,Binder实体位于Server对象中,该对象提供一套方法用以实现对服务的请求,Binder引用位于各个Client进程中。
Server提供的实现某个特定服务的访问接入点;
Client通过这个接入点向Server发送请求来使用服务。
ServiceManager使用binder_becom_context_manager(bs)命令通知Binder驱动程序自己是守户进程,它是所有进程的Server端,其他进程都作为Client端,若想获得ServiceManager远程接口,不必通过进程间通信机制获得,ServiceManger远程接口是一个特殊的Binder引用,它的引用名柄一定是0.该Binder实体没有名字也不需要注册,所有client都认为handle值为0的引用是专门与SM通信用的。
获取ServiceManager远程接口对象就是获取ServiceManagerProxy对象,它是一个IServiceManager接口,它是通过调用Framework层的ServiceManager.getIServiceManager()方法获得,而ServiceManager.getIServiceManager是通过调用Native层的ServiceManagerNative.asInterface(new BinderProxy())获得的,asInterface()方法获取到的是一个BpProxy对象,通过IPCThreadState来调用Binder驱动。而new BinderProxy()则是将Native层的Bp proxy对象转化成Java中的BinderProxy对象。
ServiceManagerProxy它本质上是一个BpServiceManager,它包含一个名柄为0的Binder引用。
Server注册服务是通过调用ServiceManager.addService("xxx", new xxxService())
(1) new xxxService()调用的是xxxService()的构造函数,xxxService继承自IxxxService.Stub类,而Stub类继承自Binder类,它的构造函数用于创建Native层的JavaBBinderHolder对象,并把对象保存在Binder的mObject中。
(2) addService()函数主要有三步:
a) 获得Parcel类型的data和reply;
b) 调用data.writeStrongBinder(service)
c) 调用mRemote.transact(ADD_SERVICE_TRANSACT, data, reply, 0)
server通过调用SM的addService函数,传递一个字符串和实际Binder对象在自己虚拟空间的地址到Binder驱动,Binder驱动记录下该地址,在SM申请的物理内存中分配一个虚拟地址并连同字符串一起传给SM,Binder驱动会记录下两个地址间对应关系。
IServiceManager.getService("xxx")
IServiceManager是一个IxxxService.Stub.asInterface(ServiceManager.getService("xxx))对象,它查询是否属于本地进程,属于则直接返回BbBinder,不属于则返回android.os.IxxxService.Stub.Proxy()对象;
ServiceManager.getService("xxx)则是调用ServiceManagerProxy.getService("xxx"),它会调用mRemote.transact()方法;
client通过调用SM的getService函数,将一个字符串传给SM,SM将相应的虚拟地址传给Binder驱动,Binder驱动查询出实际对象地址,在client申请的物理内存中分配一个虚拟地址传给Binder,这样client就获得Binder的引用。
(1)通过IxxxService.Stub.asInterface通过服务端的访问通道获取BinderProxy引用对象
private ServiceConnection mService = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mCalcAidl = IxxxService.Stub.asInterface(service);
}
};
//asInterface函数查询是否属于本地进程,是则返回BBinder对象本身,不是,则返回Proxy对象
public static IxxxService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof IxxxService))) {
return ((IxxxService) iin);
}
return new IxxxService.Stub.Proxy(obj);
}
(2)根据获取到的IxxxService访问服务端方法,它的调用顺序如下:
a) 客户端调用的方法会进入IxxxService.Stub.Proxy类中的对应方法,先将数据打包成Parcel对象,调用mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0)方法,mRemote是BpBinder对象;
b) Binder的onTransact方法,它的子类的IxxxService.Stub类重写了onTransact方法,所以会进入子类IxxxService.Stub类的onTransact方法,根据code码标识当前调用的方法,读入数据;
c) onTransact根据不同的方法调用接口实现类方法,即我们写好的服务类的方法;
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.