Binder总结篇1-Binder原理

Binder总结篇1-Binder原理

须要学会Binder的基本使用和原理,须要的知识点有:java

  1. Linux进程和空间的概念android

  2. 虚拟地址概念git

  3. 经常使用IPC,他们的基本流程和Binder的区别缓存

  4. C/S架构基本思路,也就是Binder驱动,ServerManager,Client和Server这四个概念。安全

  5. AIDL以及支持的数据类型,包括Parcelable等,以及编写服务器

  6. Service(Android的四大组件之一),Binder等几个具体的java类使用。网络

如下是本身的一些Binder学习总结,若有侵权请联系删除。架构

Linux的进程和空间的概念

在Linux系统中,进程是分配给应用程序运行的最小描述,即一个应用程序最少有一个进程,而一个进程之间又最少有一个线程,进程给应用程序分配内存空间。ide

空间:在Linux中,为了保持系统的稳定性,分为内核空间和用户空间,内核空间的权限最高,用户空间的权限最低。好比读写文件,网络请求就是在内核空间中进行的。学习

在Linux中,存在着进程隔离,也就是进程A没法直接访问进程B的数据,他们之间各自具备独立的内存。假如他们须要进行通讯,就必须经过IPC来实现,主要是经过两个方法:copy_from_usercopy_to_user

虚拟地址

在给应用程序分配内存的时候,对于应用程序来讲,他是一片连续的内存空间,可是实际上,这些内存空间映射到具体的物理内存中是碎片化的不连续的,这个在应用程序看来是连续的空间就是经过虚拟地址实现的。经过虚拟地址,让应用程序看似拥有连续的内存空间,从而映射到具体的物理内存中。

好比,在32位系统中,能够寻址的空间长度是2的32次方,也就是4GB。

传统IPC

包括:

  1. 共享内存

  2. 消息管道

  3. Socket

  4. 信号量

这些是经常使用的IPC方法,通常而言,他们会经历两次的数据copy,共享内存除外。

第一次是发送方将数据经过copy_from_user拷贝到内核空间中,这是第一次。而后,接收方在本身的内存空间中,分配缓存区,经过copy_to_user方法把内核空间的数据复制到本身进行读取。

以下图:

对于Android系统而言,上面的几种方式都不太适合,首先对于两次的数据拷贝,存在的问题是:

  1. copy次数多耗费时间

  2. 接收方不知道须要分配多大的内存接受数据,或者是须要提早通知接受方分配而耗费时间。

对于共享内存,虽然它无需copy可是较为难以控制,安全性方面较差。

那么Binder在这方面具备什么优点呢?

  1. Binder是只须要一次数据copy,仅低于共享内存。

  2. 他基于C/S架构,职责分离又相互独立,稳定性更好。

  3. 在安全性方面,传统的IPC接收方没法获取对方可靠的进程PId,从而没法鉴别对方身份。可是在Android中,他会为每个安装好的App分配一个本身的UID,从而作到能够鉴别身份。

因此Binder是Android系统进行IPC采用的手段。那么Binder为何只是能够一次数据拷贝就好了呢?

这个就是利用虚拟内存了。Binder借助内存映射,在内核空间和接收方的用户空间的数据缓存区作了一层内存映射。也就是说,在发送方将数据拷贝到内存空间的时候,内核空间的这部分地址同时也会被映射到接收方的内存缓存中,这样子,就少了一次从内和空间拷贝到用户空间。

以下图:

Binder 的通讯原理

在Binder中,有四个概念,Binder驱动,ServerManager,Client以及Server,这四个部分组成了BinderC/S架构。

他跟一次网络请求很类似:Client经过域名发起请求,经过DNS域名解析器解析具体的ip地址,而后再经过路由转发到具体的Server,再而后Server将请求结果经过路由转发回Client。

在Binder的IPC中,有以下几个部分:

  1. Binder驱动

Binder驱动是一种虚拟的字符设备,注册在/dev/bindr中,其中定义了一套Binder通讯协议,负责创建进程间Binder通讯,提供了数据包在进程之间传递的底层支持。

他的角色相似路由,他是提供进程间通讯的底层支持。负责将Client端的请求转发到Server,并将Server的数据返回给Client。

2 ServerManager

他的做用相似DNS服务器,负责将Client请求的Server的Binder描述转化为具体的Server地址,以便Binder驱动将Client的请求转达到Server。当Server须要提供服务的时候,他必须先向ServerManager注册,这样子,ServerManager中,就存有一份相似key-value的数据,保存了一份Server的Binder字符名称和Binder引用的映射以便Client能够找到。

  1. Client

Client的做用是发起请求,经过Binder向ServerManager发起请求获取Server的具体地址,而后交由Binder驱动转发。

  1. Server

Server假如须要对外提供服务,他就须要先将本身注册到ServerManager中,以便被解析出来。Server在响应请求以后,就将数据经过Binder驱动再次将数据传递会Client。

这就是一次完整的IPC调用。

还有一个问题就是ServerManager的产生,由于Client/Server都是须要经过Binder与ServerManager进行通讯的,那么这个ServerManager是如何产生的呢?

  1. 在Android系统启动以后,会建立一个名词为servermanager的进程,能够查看ZygoteInit文件,在里面的main方法中,调用ZygoteforkSystemServer产生。它经过一个约定的命令BINDERSERVER_MGR向Binder驱动注册,申请成为ServerManager。Binder驱动会自动为ServerManager建立一个Binder实体

  2. 这个Binder实体的引用在全部的Client中都是0,也就是说各个Client经过0这个引用就能够与ServerManager进行通讯。

Binder的代理机制

上面是咱们的IPC过程,在这个过程当中,Client须要获取到Server端的Binder引用,那么这个引用是真正的Server引用吗,他是如何实现的呢,A进程并没有法直接获取B进程的对象。这个就是须要经过Binder的代理机制实现。

咱们在Client端,向ServerManager获取具体的Server端的Binder引用的时候,会首先进过Binder驱动,Binder驱动它并不会把真正的Server的Bind人引用返回给Client端,而是返回一个代理的java对象,该对象具备跟Server端的Binder引用相同的方法签名,这个对象为ProxyObject,他具备跟Server的Binder实例同样的方法,只是这些方法并无Server端的能力,这个ProxyObject的能力是能够经过Binder驱动,正在实现对Server的Binder进行调用,从而完成数据传递。

好比,当Binder驱动接受到Client进程的请求,就去ServerManager中查询,在ServerManager中查询到具体的Server具体以后,就建立一个Server端的Binder对象的ProxyObject,而且将该ProxyObject返回给Client 。而后Client就经过ProxyObject调用其中的方法,ProxyObject的方法再去调用Binder驱动,这个Binder驱动就去Server进程中,调用具体的Server进程的具体的Binder对象的方法,而后再经过Binder驱动返回数据给Client。

以下图

AIDL

上面咱们大概梳理了Binder调用的总体流程,知道Binder的大概原理。在Android中,是经过AIDL这一描述性接口语言实现的。

什么是AIDL:Android 接口定义语言 (AIDL)

关于如何使用AIDL将在下一篇文章在作详细使用。

参考文章

关于Binder,做为应用开发者你须要知道的所有(同时也是本文的文章图片来源)

为何Android要采用Binder做为IPC机制

Binder系列-开篇

Android 跨进程通讯:图文详解Binder机制原理

写给 Android 应用工程师的 Binder 原理剖析

相关文章
相关标签/搜索