今天的主要是来对Binder做一个较全面的介绍,为之后的深入分析做一个预热准备。
Linux IPC
首先Binder是Android中的一种独有的跨进程通信方式,简称IPC。它是专门为Android平台设计的。
那为什么要设计出Binder这个烦人的东西呢?我们都知道Android是基于Linux系统进行演变过来的,所以理应也能直接使用Linux的IPC通信方式。
所以在理解Binder的设计初衷之前,我们先来了解一下Linux系统中现有的IPC通信方式。
Linux现有的IPC通信方式有6种:
- 管道
- 信号量
- 信号
- 共享内存
- 消息队列
- socket
管道
英文为pipe,在Linux中它的本质是一个文件系统,通过一个进程以写的方式打开文件,另一个进程以读的方式进行打开文件,通过这样读写的方式,实现了进程间的通信。
只不过该文件是位于Linux内存中,所以操作管道就是以文件的方式操作Linux内存缓存区。
由于管道是通过读写文件的方式进行运作的,所以它需要进行两次数据的拷贝;分别是copy_form_user从写进程拷贝到文件内存缓存区,再通过copy_to_user从文件缓存区拷贝到读进程中。
同时管道还有大小限制,默认为4k,一旦写入端超过大小限制,管道将会阻塞。
信号量
主要作用于进程间的资源互斥访问,通过PV两种操作等待与发送信号。
P(sv):如果sv的值大于零,就给它减1;如果它的值为零,就挂起该进程的执行 V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1.
所以信号量主要是用来解决多个进程对同一资源的竞争问题,类似于多线程的同步锁。
信号
Linux中定义的一种软中断,有64种,分为可靠信号与不可靠信号,多用于消息传递与通知,不适合传递信息。
共享内存
共享内存顾名思义,允许不同的进程访问同一块内存地址空间,它也需要进行两次数据拷贝操作,分别是将数据拷贝到共享内存中,又从共享内存中间将数据拷贝出来。
但需要注意的是,共享内存是不提供同步机制。
意思就是说,在其中一个进程进行写操作时,并不能放在另一进程进行读操作。
为了解决这个问题,共享内存一般都与前面说的信号量一起使用。
消息队列
消息队列通过一个进程向另一个进程发生消息块的方式进行通信,它与管道非常类似,都需要发送与接收,数据拷贝两次。
不同点是
- 消息队列可以防止同步与阻塞问题。
- 消息队列的接收方可以进行选择性接收。
- 发送的消息块有最大限制
socket
Linux中的socket是基于C/S架构的,传输效率低,多用于跨网络与跨设备的通信。
在Android底层使用socket来进行init与zygote等进程间的通信。
最后简单的来看一张图来了解在Linux中不同进程中的通信过程。

所以通过上面的分析,Linux现有的几种IPC通信方式都不是很适合Android间的进程通信。
例如管道、共享内存与消息队列都需要拷贝两次数据,同时有的还会存在阻塞与同步问题;另外的信号、信号量与socket由于使用场景的原因,都不适合用于Android中快速的进程间的数据通信。
Binder
那么Binder通信方式是怎么样的呢?
Binder本身是基于C/S架构的,层次分明,架构稳定,同时Binder内部只需使用一次数据拷贝操作,就能达到进程间数据的通信;另外Binder还支持鉴别用户进程的Uid,为Android提供身份的验证。
我们先来通过一张图来简单看下基于Binder的进程通信过程

Binder数据通信流程是,将数据从client端拷贝到内核空间,在内核空间中会提前通过mmap方式建立与server端的内存地址映射,通过内存地址映射server端可以直接访问内核空间中的数据,从而避免将数据拷贝到server端,提高进程间的通信速度。
在整个通信的过程中主要做的事情是:
- 通过
/dev/binder打开binder驱动 - 通过
mmap建立内存地址映射 - 通过
ioctl与binder驱动交互,进行数据传输 client使用BpBinder的transact方法进行事务请求server使用BBinder的onTransact方法来接收相应的事务
由于Android中主要使用Binder来进行service的注册与获取,所以为了更好的管理service的注册,使用了ServiceManager来进行统一管理service的注册。
在service的注册过程中ServiceManager就相当于server端,内部开启loop循环,不断接收消息将注册的service保存到注册表svclist中。
最终关于Binder的整个大致流程如下图所示

其中client与server位于应用层,ServiceManager位于用户空间,binder驱动位于内核空间。
对于开发者来说,用户空间与内核空间是透明的,我们只需关注应用层client与server的实现,就可以方便的使用Binder的通信机制。
以上是对Binder的一个理论分析,接下来的一段时间,我将结合源码来分析service的注册过程,从而探索Binder的整个工作流程,感兴趣的读者可以关注一下。
更多Android进阶指南 可以扫码 解锁 《Android十大板块文档》
1.Android车载应用开发系统学习指南(附项目实战)
2.Android Framework学习指南,助力成为系统级开发高手
3.2023最新Android中高级面试题汇总+解析,告别零offer
4.企业级Android音视频开发学习路线+项目实战(附源码)
5.Android Jetpack从入门到精通,构建高质量UI界面
6.Flutter技术解析与实战,跨平台首要之选
7.Kotlin从入门到实战,全方面提升架构基础
8.高级Android插件化与组件化(含实战教程和源码)
9.Android 性能优化实战+360°全方面性能调优
10.Android零基础入门到精通,高手进阶之路
敲代码不易,关注一下吧。ღ( ´・ᴗ・` ) 🤔

被折叠的 条评论
为什么被折叠?



