参考:
Android Bander设计与实现 - 设计篇
Binder学习指南
github_Binder机制
其中的各种概念和比喻让我看的十分痛苦,不知道是我的理解能力太差,还是人类的语言太苍白。我按自己的理解整理出一下笔记。主要是对概念的梳理,刨除比喻,以简要的文字,把我从这三篇文章中理解到的内容阐述出来,理解深度也根据自己的水平来。当时内心急躁,没有细看,也没有全看。有人看到我这篇文章了,如发现问题,欢迎指正。
(Android系统所基于的)Linux内核基础知识(为什么需要跨进程)
- 进程隔离/虚拟地址空间:每个进程对应一个虚拟地址空间,不同进程数据不共享。
- 系统调用:Linux分内核空间和用户空间,应用程序存在于用户空间,不能直接访问内核空间,但可以通过系统调用间接访问。这样间接的方式可对访问权限进行限制,保证系统的安全。跨进程通信的原理,就是通过系统调用功能,使用内核空间作为桥梁,完成不同应用程序间的通信。
为什么使用Binder
- Android广泛使用跨进程通信
- 性能:Binder拷贝数据的次数少,性能比socket、管道、消息队列等方式更高效
- 安全:Binder支持对通信双方进行身份校验
Binder通信模型
- Binder驱动:“驱动”是保证计算机能操作硬件设备的一小块代码,与此类似,“Binder驱动”是Android系统中保证Binder对象能操作内核空间的一小块代码。
- Binder(对象,或实体):提供了间接访问内核空间的功能,由Server创建并向ServiceManager注册,Client可以通过对Binder对象的引用与Server进行通信。所谓注册,就是将对象的名字和引用的映射关系记录在ServiceManager中。
- Binder引用(或代理对象):Client对Binder对象所持有的引用,或称代理对象,由Binder驱动根据Binder对象创建。Client通过它可以调用Binder对象的功能,实现方式由Binder驱动完成。
- Client和Server(进程):假设发起和接收通信请求的进程分别为Client和Server。
- ServiceManager(进程):作用是将字符形式的Binder名字转化成Client中对该Binder的引用,使得Client能够通过Binder名字获得Binder引用。(ServiceManager也是一个进程,对于ServiceManager而言,其他所有的进程都是Client,也就是说,它是其他所有进程的Server。它的Binder引用是0号引用,该Binder没有名字也不需要注册。其它进程要通过0号引用向ServiceManager发起注册Binder或获取Binder引用的请求)
- Client、Server、ServiceManager运行于用户空间,Binder驱动运行于内核空间。
- 通信流程:
- ServiceManager的建立:进程向Binder驱动申请为ServiceManager,此时进程还没有区分为Client角色或Server角色,所以统称之为Service。(我理解的建立是,其他进程通过0号引用和ServiceManager建立了连接,不知道是不是这样)
- Server创建Binder对象并向ServiceManager注册。
- Client通过Binder的名字向ServiceManager查询和获取Binder引用。
- Client通过Binder引用与Server通信,Binder通过操作内核空间,实现了两者的跨进程通信。
扩展
匿名Binder:没有向ServiceManager注册的Binder对象,即该Binder对象的引用没有公开,能收到此匿名Binder引用的Client,便可以和Server建立起一条私密的通道。(具体Client怎么才能收到,在文章中没找到)
Binder的总结
- 通常意义下,Binder指的是一种通信机制。(以上的Binder是Binder对象的简称)
- 对于Server进程来说,Binder对象指的是Binder本地对象,对于Client来说,Binder对象指的是Binder代理对象。
- 对于传输过程而言,Binder对象是可以进行跨进程传递的对象。