Binder机制详解(三)

系列目录

Binder机制详解(一)

Binder机制详解(二)


前言

前两节学习了Binder机制需要储备的底层知识,接下来会分四层详细讲解Binder机制


一、Binder机制理解

binder 是 Android 中主要的跨进程通信方式,binder 驱动和 service manager 分别相当于网络协议中的路由器和 DNS,并基于 mmap 实现了 IPC 传输数据时只需一次拷贝。

binder 包括 BinderProxy、BpBinder 等各种 Binder 实体,以及对 binder 驱动操作的 ProcessState、IPCThreadState 封装,再加上 binder 驱动内部的结构体、命令处理,整体贯穿 Java、Native 层,涉及用户态、内核态,往上可以说到 Service、AIDL 等,往下可以说到 mmap、binder 驱动设备,是相当庞大、繁琐的一个机制。

二、应用层

1.Linux下的进程通信

  • 管道通信:1v1,两次拷贝

  • socket:效率低,开销大

  • 共享内存:性能高,安全性低

2.binder通信

binder通信:牺牲了开发灵活度,必须实现一个service,自己实现数据分发(通信的类,方法,数据,返回参数)—>aidl帮我们做

  • aidl.exe解析aidl配置类,生成一个java类

  • 写完AIDL文件之后,系统会在Build时生成一个继承IInterface接口的java文件。这个文件名和对应的AIDL文件名相同。在这个文件中,有一个内部类Stub,这个类就是Binder,所以可以认为AIDL是为了帮助系统生成对应的Binder文件。

  • 这个类继承了IInterface接口,同时这个类也是一个接口。这个接口申明了两个方法,也就是.aidl中的方法。然后声明了一个内部类Stub。这个Stub就是一个Binder类。在Stub内部还有个代理类Proxy,在跨进程通讯中,它会是客户端的代理方法。

proxy调用者,stub接收者

3.stub

  • 除去构造方法以外,Stub中的方法还有asBinder()asInterface()onTransact方法。在这三个方法之外,还有上文提到过的,两个静态ID,用来标识客户端调用的方法。

  • 其中asBinder()方法相当于一个get方法,用来返回当前的Binder对象

  • 接下来我们看一下onTransact()方法,这个方法运行在服务端,会通过code来分发具体要执行的方法(避免方法乱套)

  • asInterface()方法:判断当前服务端和客户端是否处于同一进程中。如果处于同一个进程中,会返回同一个Stub对象本身,如果处于不同的进程会返回封装后的客户端代理类Stub.proxy。这个方法会在客户端调用,用来获取对象。

4.流程总结

客户端—>proxy中请求函数—>通过remote写入(code,data,返回值,类)—>mRemote—>transact(JNI层实现)写入到系统中—> 通知服务端进程—>onTransact通过code—>调用服务端request—>结果—>写入客户端进程

三、native层

进程间通信本质:内存拷贝

  • 用户空间:存放程序的代码和数据

    内核空间:存放内核代码数据

    应用程序需接口申请才能调用代码在内核空间中运行,好处:应用程序崩溃不会导致内核崩溃

    计算机蓝屏主要是硬件驱动(在内核空间)不兼容导致

  • 物理内存

    虚拟内存:用户空间和内核空间都属于虚拟内存

  • MMU内存管理单元:cpu想要访问一个地址,通过MMU(PTE表)去取

    CPU在执行指令与数据时,获得的是虚拟内存的地址,但是CPU只能去物理内存寻址。此时,MMU就派上用场了。MMU负责,将虚拟地址,翻译成,真正运行时的物理地址。

1.Binder基于mmap如何实现一次拷贝

(binder驱动)内核空间和(接收方进程)用户空间映射到同一块物理内存上
发送方进程copy_from_user—>Binder驱动(内核空间)<—>mmap映射物理页alloc_page,接收方进程<—>mmap映射物理页alloc_page

  • 内核刚开始只是分配了一个物理页,并且分别将这个物理页映射到进程的内核虚拟地址空间V1(修改内核空间的页表映射)和进程的用户虚拟地址空间V2(修改用户空间的页表映射)。在用户空间访问V1和在内核空间访问V2,其实都是访问的是同一个物理内存块,从而实现进程的内核和用户空间共享同一块物理内存的目的。这样binder驱动在内核空间,将一段数据拷贝到这个物理页,则该进程的用户空间则不需要copy_to_user()即可以同步看到内核空间的修改,并能够访问这段物理内存

2.Intent传参大小限制

4M,mmap映射时会判断大小

初始化binder—>binder_open(路径)—>mmap映射—> binder_loop不断解析分发物理内存中数据

四、驱动层

service manager(单独进程):运行binder,实现android进程间通信,父进程是init进程

  • init—>service manager

  • init—>zygote—>systemServer

copy_from_user:用户空间拷贝到内核空间(驱动)

Binder驱动核心是维护一个binder_proc类型的双向链表,里面记录了servicemanager在内的所有service信息,当client去请求某个service时,binder驱动去binder_proc中查找相应的service返回给client,同时增加service的引用个数

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Binder机制Android系统中一种进程间通信(IPC)的机制,用于在不同进程之间进行数据交换和通信。通过Binder机制Android应用程序可以实现进程间的数据共享和相互调用。 Binder机制基于C/S架构,主要由服务端、客户端和Binder驱动组成。服务端提供一个或多个服务,将其注册到Binder驱动中,并通过Binder对象发送和接收数据;客户端通过获取服务端的Binder对象,与其进行通信和交互;而Binder驱动负责管理Binder对象的创建、销毁和通信。 在Binder机制中,Binder对象充当了交互的桥梁。每个Binder对象都有一个唯一的标识符(具体是一个32位的整数),用于识别和查找对应的服务端。通过Binder对象,客户端和服务端可以进行方法调用、数据传输等操作。服务端通过Binder对象将数据发送给客户端,客户端通过Binder对象将数据传递给服务端。 Binder机制设计了多种数据结构来实现进程间通信,如BpBinder、BpRefBase、Parcel等。BpBinder负责处理进程间的通信,并通过Binder Proxy将方法调用转发给服务端;BpRefBase用于引用计数,确保对象在不再使用时能够正确释放;Parcel用于在进程间传递数据,可以实现序列化和反序列化。 总结来说,Android Binder机制Android系统中一种进程间通信的机制,通过Binder对象实现不同进程之间的数据交换和通信。通过服务端、客户端和Binder驱动的协作,应用程序可以实现进程间的数据共享和相互调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值