Binder学习总结

目录

一、Binder 与AIDL的关系

二、大致流程:

三、Binder优点:

四、实现原理:

五、Binder相关类介绍:

附:


一、Binder 与AIDL的关系


Binder是跨进程通信的一种方式,AIDL是使用Binder的封装的一个模板、一种简单方法。


二、大致流程:

  1. 服务端启动时,IPCThreadState::joinThreadPool 会创建一个死循环线程,不断监听来自客户端的消息,然后调用executeCommand去执行,会调BBinder::transact--onTransact,而实现的本地服务会继承BBinder,实现onTransact方法。
  2. Server向ServerManager注册;
  3. Client通过ServerManager查询Server,并借助Binder驱动返回Server的引用; (并不是所有用来通信的binder都要注册到SM中,也可以通过创建的Binder连接直接把Binder实体给Client调用)

注意:startThreadPool会创建一个新线程,里面也会调用joinThreadPool。参考StartThread Pool和join Thread Pool分析Binder服务的调用对象和Binder服务处于同一进程。

调用流程:
AIDL文件编译后会生成一个对应的java文件,里面是个继承了AIDL接口的proxy.
Client调用函数如add时,调用proxy的add方法,会通过Remote.transact 函数名和参数。
Binder 调用transactNative,底层会调用底层Binder驱动,终会调用Binder的execTransact,里面会调用onTransact。而Stub类重写了onTransact()方法,里面会调用服务端的add方法。

在这里插入图片描述

参考:Binder通信机制与AIDL的基本使用

640?wx_fmt=jpeg

(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真正的实现。

注意事项
Client持有自己Binder的实体,Server端持有其引用;Server端持有其自己Binder的实体,Client持有其引用。
ServerManager是一个进程、Server又是另一个进程。


三、Binder优点:


相比于内存共享:实现方便、方便管控;可知道对方的PID等;
相比于管道和消息队列等:数据只需一次拷贝,省时;

四、实现原理:


内存映射mmap:简单的讲就是将用户空间的一块内存区域映射到内核空间。映射关系建立后,用户对这块内存区域的修改可以直接反应到内核空间;反之内核空间对这段区域的修改也能直接反应到用户空间。

Client持有Binder引用;Server端持有Binder实体。

五、Binder相关类介绍:


IBinder : IBinder 是一个接口,代表了一种跨进程通信的能力。只要实现了这个借口,这个对象就能跨进程传输。
IInterface : IInterface 代表的就是 Server 进程对象具备什么样的能力(能提供哪些方法,其实对应的就是 AIDL 文件中定义的接口)
Binder : Java 层的 Binder 类,代表的其实就是 Binder 本地对象。BinderProxy 类是 Binder 类的一个内部类,它代表远程进程的 Binder 对象的本地代理;这两个类都继承自 IBinder, 因而都具有跨进程传输的能力;实际上,在跨越进程的时候,Binder 驱动会自动完成这两个对象的转换。
Stub : AIDL 的时候,编译工具会给我们生成一个名为 Stub 的静态内部类;这个类继承了 Binder, 说明它是一个 Binder 本地对象,它实现了 IInterface 接口,表明它具有 Server 承诺给 Client 的能力;Stub 是一个抽象类,具体的 IInterface 的相关实现需要开发者自己实现。

========================

RefBase:指针基类
IBinder 继承RefBase,IBinder.h: 申明binder的必要方法;
BBinder 继承IBinder;在Server进程中,BBinder为Binder本地对象提供了抽象的进程间接口.
BpBinder 继承IBinder;Binder proxy ,在Client进程中;
BBinder和BpBinder的功能并不是对称的,改成BnBinder可能更形象: Binder Native。
BnInterface 继承BBinder;    在Server进程中。
BpInterface 继承BpRefBase;BpRefBase继承RefBase,为Binder代理对象提供了进程间通信的接口

asInterface 完成的是Binder到Interface的转换,具体就是:BBinder->BnInterface;BpBinder->BpInterface。
而asBinder功能则相反,具体是:BnInterface->BBinder;BpInterface->BpBinder

Binder代理对象    类型为BpBinder,在用户空间创建,且执行在Client进程中.会被Client进程中的其他对象引用,另外会引用Binder驱动程序中的Binder引用对象.
Binder引用对象    类型为binder_ref,在Binder驱动程序中创建,被Binder代理对象引用.
Binder实体对象    类型为binder_node,在Binder驱动程序中创建,被Binder引用对象所引用
Binder本地对象    类型为BBinder,在用户空间中创建,且执行在Server进程中.会被Server进程中其他对象引用,还会被Binder实体对象引用.

ProcessState是负责打开Binder节点并做mmap映射,IPCThreadState是负责与Binder驱动进行具体的命令交互。
getService@ServiceManagerProxy-->transact@BinderProxy-->transact@BpBinder-->transact@IPCThreadState

Binder传输最大数据:普通的由Zygote孵化而来的用户进程,所映射的Binder内存大小是不到1M的,准确说是 110241024) - (4096 *2) :这个限制定义在ProcessState类中。

 


附:

Binder一些疑难点详解:参考深入理解Binder通信原理

猜你喜欢

转载自blog.csdn.net/lanmengfenghe/article/details/107080381