1、主要内容
Binder在Android中有举足轻重的地位,不论是Activty的启动流程,仍是四大组件的通信方式都一一和binder有着细密的关联。 主要从四个大方向介绍Binder:
- Binder由来和特性:首先是对Binder有个完整的认识和他存在的优点分析
- Linux下IPC原理:Android是基于Linux的,因此先了解下Linux固有的进程通信的方式有助于对Binder的理解
- Binder原理:主要包括组件的构成、架构和通信原理
- Binder有关的常见问题:一些常见的和不常见的有关Binder的问题有助于更好的理解和加深对Binder的认识
2、Binder概述
1.什么是Binder?
- 从IPC角度来讲:Binder是Android中的一种跨进程通讯方式,该通讯方式在linux中没有,是Android独有;
- 从Android Driver层:Binder还能够理解为一种虚拟的物理设备,它的设备驱动是/dev/binder;
- 从Android Native层:Binder是建立Service Manager以及BpBinder/BBinder模型,搭建与binder驱动的桥梁;
- 从Android Framework层:Binder是各类Manager(ActivityManager、WindowManager等)和相应xxxManagerService的桥梁;
- 从Android APP层:Binder是客户端和服务端进行通讯的媒介,当bindService的时候,服务端会返回一个包含了服务端业务调用的 Binder对象,经过这个Binder对象,客户端就能够获取服务端提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务。
2.由来?
Android 系统是基于 Linux 内核的,Linux 已经提供了管道、消息队列、共享内存和 Socket 等 IPC 机制。那为何 Android 还要提供 Binder 来实现 IPC 呢?主要是基于性能、稳定性和安全性几方面的缘由。linux
- 管道:任何进程都能通信,但速度慢
- 消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题。
- 共享内存:可以容易控制容量,速度快,但要保持同步,好比写一个进程的时候,另外一个进程要注意读写的问题,至关于线程中的线程安全。固然,共享内存一样能够做为线程通信,不过没有这个必要,线程间原本就已经共享了同一个进程内的一块内存。
- socket:本机进程之间能够利用socket通讯,跨进程之间也可利用socket通讯,一般RPC的实现最底层都是经过socket通讯。socket通讯是一种比较复杂的通讯方式,一般客户端须要开启单独的监听线程来接受从服务端发过来的数据,客户端线程发送数据给服务端,若是须要等待服务端的响应,并经过监听线程接受数据,须要进行同步,是一件很麻烦的事情。socket通讯速度也不快。
3.Binder特性?
3.1 性能?
- 共享内存虽然无需拷贝,但控制复杂,难以使用。
- Binder 只须要一次数据拷贝,性能上仅次于共享内存。
- Socket 做为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通讯和本机上进程间的低速通讯。
- 消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,而后再从内核缓存区拷贝到接收方缓存区,至少有两次拷贝过程。
3.2 稳定性?
- Binder 基于 C/S 架构,客户端(Client)有什么需求就丢给服务端(Server)去完成,架构清晰、职责明确又相互独立,天然稳定性更好。
- 共享内存虽然无需拷贝,可是控制负责,难以使用。从稳定性的角度讲,Binder 机制是优于内存共享的。
3.3 安全性?
- 首先传统的 IPC 接收方没法得到对方可靠的进程用户ID/进程ID(UID/PID),从而没法鉴别对方身份。
- Android 为每一个安装好的 APP 分配了本身的 UID,故而进程的 UID 是鉴别进程身份的重要标志。传统的 IPC 只能由用户在数据包中填入 UID/PID,但这样不可靠,容易被恶意程序利用。可靠的身份标识只有由 IPC 机制在内核中添加。其次传统的 IPC访问接入点是开放的,只要知道这些接入点的程序均可以和对端创建链接,无论怎样都没法阻止恶意程序经过猜想接收方地址得到链接。
- 同时 Binder 既支持实名 Binder,又支持匿名 Binder,安全性高(Binder.getCallingUid())。
3.4 结论:
3、Linux下IPC原理
1.进程隔离
- 进程与进程间内存是不共享的。两个进程就像两个平行的世界,A 进程无法直接访问 B 进程的数据,这就是进程隔离的通俗解释。
- A 进程和 B 进程之间要进行数据交互就得采用特殊的通讯机制:进程间通讯(IPC)。
2.用户空间与内核空间
- 每一个Android的进程,只能运行在本身进程所拥有的虚拟地址空间。对应一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间,固然内核空间的大小是能够经过参数配置调整的。对于用户空间,不一样进程之间彼此是不能共享的,而内核空间倒是可共享的。
- 简单的说就是,内核空间(Kernel)是系统内核运行的空间,用户空间(User Space)是用户程序运行的空间。为了保证安全性,它们之间是隔离的。
3.用户态与内核态
-
虽然从逻辑上抽离出用户空间和内核空间;可是不可避免的的是,总有那么一些用户空间须要访问内核的资源;好比应用程序访问文件,网络是很常见的事情,怎么办呢?面试
-
当一个任务(进程)执行系统调用而陷入内核代码中执行时,咱们就称进程处于内核运行态(内核态)此时处理器处于特权级最高的(0级)内核代码中执行。当进程在执行用户本身的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。处理器在特权等级高的时候才能执行那些特权CPU指令。缓存
-
系统调用主要经过以下两个函数来实现:安全
copy_from_user() //将数据从用户空间拷贝到内核空间
copy_to_user() //将数据从内核空间拷贝到用户空间
复制代码
4、Binder原理
4.1 Binder组成
Binder 是基于 C/S 架构的。由一系列的组件组成,包括 Client、Server、ServiceManager、Binder 驱动。其中 Client、Server、Service Manager 运行在用户空间,Binder 驱动运行在内核空间。其中 Service Manager 和 Binder 驱动由系统提供,而 Client、Server 由应用程序来实现。Client、Server 和 ServiceManager 均是经过系统调用 open、mmap 和 ioctl 来访问设备文件 /dev/binder,从而实现与 Binder 驱动的交互来间接的实现跨进程通讯。
-
Clientbash
如同互联网中客户端(Client),Binder是Server本地对象的一个引用,这个引用其实是一个代理对象,Client经过这个代理对象来间接访问Server的本地对象;服务器
-
Server网络
如同互联网中服务器(Server),Binder是提供具体实现的本地对象,需向ServiceManager注册;架构
-
ServiceManagersocket
如同互联网中DNS域名服务器(ServiceManager),管理Servive注册和查询,做用是将字符形式的 Binder 名字转化成 Client 中对该 Binder 的引用,使得 Client 可以经过 Binder 的名字得到对 Binder 实体的引用。注册了名字的 Binder 叫实名 Binder,就像网站同样除了除了有 IP 地址意外还有本身的网址。函数
-
驱动
如同互联网中路由器(Binder 驱动),是整个通讯的核心;驱动负责进程之间 Binder 通讯的创建,Binder 在进程之间的传递,Binder 引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。
4.2 Binder架构
Binder架构采用分层架构设计,每一层都有其不一样的功能,以你们平时用的startService为例子,AMP为ActivityManagerProxy,AMS为ActivityManagerSerivce。BpBinder是Client端建立的用于向Server发送消息的代理,而BBinder是Server端用于接受消息的通道。
- Binder 通讯采用 C/S 架构,从组件视角来讲,包含 Client、 Server、 ServiceManager 以及 Binder 驱动,其中 ServiceManager 用于管理系统中的各类服务。
- Binder 在 framework 层进行了封装,经过 JNI 技术调用 Native(C/C++)层的 Binder 架构。
- Native 层: 对于Native层,若是须要使用Binder,则能够直接使用BpBinder和BBinder(也包括JavaBBindder)便可,对于上一层Java IPC通讯也是基于这个层面。
- Kernel物理层:这里是Binder Driver,前面三层都跑在用户控件,对于用户控件内存资源是不共享的,每一个Android的进程只能运行在本身基础讷航所拥有的虚拟地址空间,而内核空间倒是可共享的。真正通讯的核心环节仍是Binder Driver。
4.3 Binder机制通信原理
- Server向ServiceManager注册Server经过Binder驱动向ServiceManager注册,声明能够对外提供服务。ServiceManager中会保留一份映射表。
- Client向ServiceManager请求Server的Binder查询Client想要请求Server的数据时,须要先经过Binder驱动向ServiceManager请求Server的Binder引用:我要向名字为zhangsan的Server通讯,请告诉我Server的Binder引用。
- 向具体的Server发送请求Client拿到这个Binder引用后,就能够经过Binder驱动和Server进行通讯了。
- Server返回结果Server响应请求后,须要再次经过Binder驱动将结果返回给Client。
4.4 总结
- 从进程间通讯的角度看,Binder 是一种进程间通讯的机制;
- 从 Server 进程的角度看,Binder 指的是 Server 中的 Binder 实体对象;
- 从 Client 进程的角度看,Binder 指的是对 Binder 代理对象,是 Binder 实体对象的一个远程代理
- 从传输过程的角度看,Binder 是一个能够跨进程传输的对象;Binder 驱动会对这个跨越进程边界的对象对一点点特殊处理,自动完成代理对象和本地对象之间的转换。
5、Binder有关问题