前言

本篇文章记录本人对Binder的学习,因为本人能力有限,若有错误,还请批评指正。
binder的使用文章推荐

1.Binder是什么?

  • 可以理解是为Android的血管。是一种进程间通信的机制。比如Activity,Service需要和AMS通信的时候,就需要Binder。
  • 除了进程间通信,也可以把Binder理解为一种虚拟物理设备驱动。虚拟表示没有实体,和键盘鼠标不一样。Binder是虚拟的。因为mmap映射时将虚拟内存映射到/dev/binder文件,在linux中这个代表一个驱动,所以说它是一种虚拟物理设备驱动。
  • 除此之外,在应用层,也可以把Binder理解为一个是一个能发起进程间通信的Java类,实现了IBinder接口。除此之外,AIDL中的Stub,Proxy也实现了IBinder,还有AMS等也实现了IBinder。另外在ServiceManager中查找服务时,所用到的Map集合的value也是IBinder类型的。

综上所述,Binder可以说是:
①进程间通信的机制
②虚拟物理设备驱动
③一个能发起进程间通信的Java类

2.为什么是Binder?

Linux也有一些很优秀的进程间通信机制,例如管道,消息队列,共享内存,socket等,但是为什么Android使用Binder而不是这些呢?
看Binder与共享内存,socket的对比

参考指标 Binder 共享内存 socket
性能上 需要拷贝1次 需要拷贝0次 需要拷贝2次
架构上 C/S架构,很稳定,且易用 难以控制,易用性差 C/S架构(但是是一款通用的接口,传输效率低,开销大)
安全性上(最重要) ①为每个APP分配UID②支持实名和匿名访问 不分配UID,访问接入点是开放的,不安全 不分配UID,访问接入点是开放的,不安全

解释下这幅图:

2.1 拷贝次数

(1)传统的IPC通信(两次拷贝)
基础知识:内存被操作系统划分成了两块:用户空间和内核空间,用户空间是用户程序代码运行的地方,内核空间是内核代码运行的地方,为了安全,它们是隔离的。即使用户的程序崩溃了,内核也不受影响。同时,内核空间映射到物理内存中是一块的,而用户空间,不同进程映射到的物理内存不一样。(所以内核空间的数据是共享的,从下面的图也可以看出来)
我们软件工程师所说的内存一般都是虚拟内存。

下面是我自己画的图,描述了传统IPC的过程

当需要进程间通信时,数据会先从进程1的用户空间,通过系统调用copy_from_user进入内核空间,然后再通过系统调用copy_to_user进入进程2的用户空间,从而完成通信。

可以看到,传统的IPC需要两次拷贝,每次拷贝都需要系统调用,上下文切换。
(2)Binder通信(一次拷贝)

可以看到,数据也会先从进程1的用户空间到系统的内核空间,完成一次拷贝,但是进入系统内核空间后,进程2的用户空间的数据接收区和内核空间的那部分区域,能够映射到同一块物理空间。这样就不用发生copy_to_user的系统调用了,从而不用第二次拷贝。
用到了mmap,即内存映射。即内存上的空间可以映射到磁盘上的对应区域(操作系统学过)
(3)共享内存(0次拷贝)

可以发现,它把copy_from_user省略掉了,直接就是进程1和进程2能够共享同一块物理内存,不需要拷贝。这样看似效率很高,但是实则易用性很差。因为程序员的水平是参差不齐的。这个技术本身没有问题,有问题的是使用这个技术的人。所以我觉得Binder的一次拷贝是故意的,目的是提高易用性。后面的mmap是谷歌工程师完成的,我们只需要让服务类继承Binder,那么它就具有了进程间通信的能力了。至于具体的细节,谷歌工程师已经帮我们封装好了。但是因为客户端太灵活了,情况很多,难以统一,所以谷歌工程师不能帮我们实现客户端这边的封装。

2.2 架构

这个其实就是C/S架构的好处,客户端有什么需求就丢给服务器,解耦,很稳定。而且很易用(Binder需要拷贝一次,而不是零次,为的就是易用性更高),程序员只需要关心业务本身代码,无需过度关注进程通信细节。
而共享内存的话,需要面临一系列复杂的问题,比如访问的安全性,同步等问题。

2.3 安全性

这个要分两方面来说
①首先Binder为每个app分配了一串UID,这串UID是app的唯一身份标识。而共享内存,socket等都是app自己生成类似的这种编码,直接交给上层,上层只管接收,没有能力去甄别对错。假如有恶意软件伪装,那么是无法跟踪这个软件的。
②其次是支持实名访问和匿名访问。实名访问的话,和共享内存,socket是一样的,这样安全性较低。匿名访问安全性高,我们自己写的AIDL一般就是匿名访问。匿名访问类似于滴滴打车,打过来的手机号是虚拟的,并不是实际的,也就是一个代理对象。

区分实名访问和匿名访问的标准是,有无在ServiceManager注册过。注册过的就是实名,反之就是匿名。
比较常见的实名如AMS,WMS等

3.mmap介绍

3.1 mmap是什么?

mmap 是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用 read、write 等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。

3.2 mmap实现的c++


同时,使用mmap一般都要创建文件,因为linux一切皆文件。

4.AIDL是什么?

关于AIDL的参考文章

(1)定义

AIDL全程是Android Interface Difination Language,即接口定义语言,是用于定义服务器和客户端通信接口的一种描述语言,可以拿来生成用于IPC的代码。目的就是实现进程间通信。
其实它就是一个模板,真正起作用的不是AIDL文件,而是编译后,根据AIDL文件生成的那个Interface类。

(2)AIDL文件编译后的组成

以这样的AIDL文件为例

此AIDL文件在编译后,会生成这样一个interface

TestAidl接口里面有两部分
一个是静态抽象内部类Stub,一个是接口待实现的方法add
其中,Stub又实现了TestAidl接口。但是又因为Stub是抽象类,所以不必实现add方法,add方法的具体实现在具体的服务类里面。也就是Stub的子类

下面来看一下Stub的组成

看起来有点乱,但其实可以分成以下几部分

抽象类Stub 继承Binder  实现TestAidl{①静态的asInterface方法{返回代理类(分两种情况:同进程,直接返回继承该Stub的Binder;不同进程,返回静态代理类)}②重写的onTransact方法③静态代理类Proxy  实现TestAidl{实现add方法,主动调用transact方法}}

①一个是asInterface方法,如果是同一进程的,则直接返回继承该Stub的服务端对象,如果不是同一进程,则构造一个代理类,由这个代理类,来间接操作这个服务端对象。
②一个是onTransact方法,此方法在客户端调用transact方法时调用。下图是onTransact方法的代码

code是方法的代码,是一个int类型,因为客户端和服务端都实现同一个接口,那么他们都会实现同一批方法(在这里就是add方法),那么就可以为这一批方法进行统一编序号,方便方法的匹配调用。
③还有一个是静态代理类,它是对服务端的代理。里面的代码如下

会发现它和Stub的代码很像。没错,其实它代理的就是Stub的实现类,所以这是正常现象。我们再看add方法,里面有两个Parcel类型的变量,分别负责接收发送的参数,接收返回的数据。这里面就有transact方法的调用,这里调用就会调用到onTransact方法。transactonTransact方法的四个参数分别表示的含义为:
①用于区分执行哪个方法
②客户端传递的参数
③服务器返回回去的值
④标明是否有返回值,0表示有,1表示没有

(3)AIDL进行进程间通信的流程

①客户端调用bindService,在onServiceConnected的回调方法中,调用StubasInterface方法,得到mRemote值。(如果是同一进程,直接返回服务端对象。如果是不同进程,返回代理对象)。这里假设是不同进程
②客户端调用mRemoteadd方法,因为是不同进程,所以调用代理对象的add方法。
add方法里面会调用transact方法,然后客户端阻塞直到方法执行完成,拿到返回值。
④客户端调用transact方法,会调用服务端StubonTransact方法,里面会执行Stub子类即具体服务类的add方法。

Binder机制原理相关推荐

  1. binder机制原理分析(一):ServiceManager 进程启动

    binder机制原理分析一共分5个部分,其实省了一点,但是分析到后面都差不多了,以后再补充吧. 1.ServiceManager 进程启动 2.普通Service注册到ServiceManager 3 ...

  2. Binder机制原理、源码、AIDL,IBinder,Binder,IInterface,BinderDriver,需要的都在这里了

    导读: 本文分为三个阶段, 第一阶段,原理概述,力争说人话的基础上,讲明白Binder机制在搞什么,为什么这样搞,以及具体是怎么搞的. 第二阶段,代码层面描述,主要描述了,AIDL.IBinder.B ...

  3. 理解Android Binder机制原理

    原文地址: http://blog.csdn.net/universus/article/details/6211589 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥 ...

  4. 从 Android 6.0 源码的角度剖析 Binder 工作原理 | CSDN 博文精选

    在从Android 6.0源码的角度剖析Activity的启动过程一文(https://blog.csdn.net/AndrExpert/article/details/81488503)中,我们了解 ...

  5. Android跨进程通信Binder机制与AIDL实例

    文章目录 进程通信 1.1 进程空间划分 1.2 跨进程通信IPC 1.3 Linux跨进程通信 1.4 Android进程通信 Binder跨进程通信 2.1 Binder简介 2.2 Binder ...

  6. Binder通信机制原理解析

    Binder是什么?Binder有啥用?作为一个应用开发者,如果我们开发的应用不涉及跨进程通信(IPC),我想我们也不会去接触Binder.但不知你有没有发现,近来的Andorid面试,都会问及And ...

  7. Binder原理,Binder机制

    写的很好的文章,通俗易懂, 做个记录 Binder机制,从Java到C (1. IPC in Application Remote Service) Binder机制,从Java到C (2. IPC ...

  8. AndroidBAT高级面试合集——Binder 通信原理与机制,音视频开发工程师

    Binder 驱动运行在内核空间,它就是那个内核模块了.Binder 驱动很重要,承 担了进程间通信的数据转发等.一提到驱动,也是比较熟悉,你插个 U 盘,需 要驱动吧.而 Binder 驱动也差不多 ...

  9. 理解 Android 的 Binder 机制

    Binder机制的工作流程 1.客户端获取服务端的代理对象(proxy).我们需要明确的是客户端进程并不能直接操作服务端中的方法,如果要操作服务端中的方法,那么有一个可行的解决方法就是在客户端建立一个 ...

  10. Binder相关面试总结(三):Binder机制是如何跨进程的

    Android中进程和线程的关系和区别 线程是CPU调度的最小单元,同时线程是一种有限的系统资源:而进程一般指一个执行单元,在PC和移动设备上指一个程序或者一个应用. 进程有自己独立的地址空间,而进程 ...

最新文章

  1. python退出帮助系统help应该使用exit_简明Python3教程 5.第一步
  2. 【数字信号处理】线性常系数差分方程 ( 根据 “ 线性常系数差分方程 “ 与 “ 边界条件 “ 确定系统是否是 “ 线性时不变系统 “ 案例 | 根据 “ 线性时不变系统 “ 定义证明 )
  3. 在ASP.NET中上传图片并生成缩略图
  4. T-SQL Recipes之Customized Database Objects
  5. mapreduce实现计数时未执行reduce方法(未实现统计功能)
  6. Silverlight 布局控件
  7. gdb好文章:GDB十分钟教程
  8. 通过boundingRectWithSize:options:attributes:context:计算文本尺寸
  9. php判断网址包含字符,php中判断一个字符串包含另一个字符串的方法
  10. int 转string
  11. 【机器学习】主成分分析 (PCA)、无监督特征提取
  12. 2020-12-27
  13. 2018-9-15AGV项目笔记
  14. linux嗅探网站结构,Linux下的Dsniff嗅探浅析
  15. python编程题3.5:恺撒密码
  16. empty 和 isset 的区别
  17. python之dict
  18. 移动硬盘部分分区不能识别解决方法
  19. AI开发过程中常用开发命令及软件安装
  20. Android_001_校园APP_001_底部导航栏_Fragment_0

热门文章

  1. 推荐一个清理自己电脑磁盘的磁盘容量图形化软件--WinDirStat
  2. 第3章-线性概率模型(1)-logistics/probit模型
  3. C语言全局变量,局部变量,静态局部变量的区分
  4. ABB伺服驱动调试(三)
  5. TwinCAT 3 EtherCAT控制伺服
  6. 【Oracle】执行计划详解
  7. 程序员考哪些证书有利于职业发展?
  8. Java数组集合转换
  9. 量子力学 一 基础5 厄尔米特算符与酉算符 算符的谱分解
  10. 计算机硕士工资一览表 (时间有点久远了)