0%

(02)2021.12.12-Binder机制与常见面试题讲解---Leo老师

一、储备知识

很多同学回答 Binder 是什么的时候,只会说 Binder 是一种进程间通信机制,这是不完善的,我们要说出以下 3 个点才算完整:

  • 机制:Binder 是一个进程间通信机制
  • 驱动: Binder 是一个虚拟物理设备驱动
  • 应用层:Binder 是一个能发起通信的 Java 类(Service里面就有用到Binder类)

Linux 一切皆文件

多进程的好处?

  • 突破内存限制,如图库内存占用过多
  • 功能稳定性,比如长连接,独立进程
  • 规避内存泄漏,比如 webview 正常使用会有内存泄漏
  • 隔离风险: 不稳定的功能放入独立的进程,比如dump 内存

为什么Android采用 Binder:

  • 性能: 只需要一次
  • 特点:基于C/S,易用性高(如共享内存使用很复杂,参考多线程共享变量,涉及的线程安全加锁)
  • 安全性,为每个App分配 UID,同时支持匿名和实名。公交车,只要能到那里,都能坐车;Binder 既有实名又有匿名,实名的服务是大家都可以访问,比如 AMS、WMS ,匿名服务,类似滴滴打车,你是不能直接联系到司机的,只能通过滴滴给你虚拟号。匿名服务只能通过代理去真正获取服务。(实名和匿名的区别在于是否注册)。

自己写的服务可以实名吗?是可以的,调用 API 即可

一个进程会分为 用户空间和内核空间。如果是 32位系统(总共有 2^32 这么大,即 4G),那么用户空间一般 3G,内核空间 1G

所有进程的内核空间都是映射到物理内存上是同一块空间,

内核空间是地球仪,物理内存是地球;进程1的用户空间是 月球仪器,对应的物理内存是月球;进程2的用户空间是火星仪,对应的物理内存是火星。

我们平时说的拷贝次数,指的就是 copy_from_user 或者 copy_to_user 这种系统调用,每调用一次就是所说的类似 Binder 只用拷贝一次这种说法。

为什么只关心这个系统的调用呢?这是因为在用户态和内核态切换非常耗时,它有上下文切换的,需要保存当前运行状态。

传统的IPC就是 copy_from_user ,接着再 copy_to_user ,2次

服务端和内核端,google 已经实现了,所以开发者只要开发 客户端。降低 Binder 的使用难度

为什么不从两个应用之间映射?还需要经过内核?

老师说的是,如果直接2个应用之间,就变成了 内存共享,google 做 Binder 就是因为内存共享比较难控制,所以宁愿用 Binder 来浪费一次性能。感觉说服力不够,得自己想想。

二、Binder

MMKV 也是使用 mmap 实现的。

2.1 AIDL 生成的类细节

AIDL 类似黄牛,帮我们代办一些事情,降低办事的复杂度。帮我们生成 Java 代码。AIDL 生成的 Java 代码,我们自己去手写也是一样的。

Proxy 是给客户端使用的,Stub 服务端使用。asInterface 判断如果是跨进程,那么返回的是代理对象,否则,返回的是本身。Binder 通信会创建 2个 Parcel ,一个是数据包,一个是结果包。

ServiceManager 也是个服务,它的 handle 句柄是固定的: 0 。Service 创建之后,可以去 ServiceManager 中注册,建立 Service 和 handle 句柄的映射关系。

客户端调用 transact 方法的时候,服务端那边就会响应 onTransact 方法。我们一般调用一个类的方法,可以写明全路径,比如一般是: com.xx.haha.Demo ,但是在 Binder 中,觉得传全路径过去占用的空间比较大,所以对方法做了精简,比如,用 1 代表 addPerson、2代表getPersonList 等,节约空间。这个体现在 Stub 中的那些静态常量。

onTransact 中,如果调用的方法没有返回值,则执行完就完了;否则,将执行结果写到 reply 中。 客户端调用服务端一般是同步的,所以计算过程客户端会挂起,所以一般要在子线程去做这种Binder 调用。如果要使用异步调用,就使用 oneWay

2.2 Intent 为什么不能传送大的数据

为什么只能 1M - 8k ?这是因为 Binder 是一个驱动,通过 mmap 创建的空间大小就是 1M - 8k (就是 1M - 2 * pageSize ,pageSize 是 4k),如果是异步的话 ,则是 (1M - 8k)/2 。

至于为什么是 1M - 8k ,那总得给个数字,不可能无限大。可能是为了充分利用存储空间。

mmp 最开始只会给 1 页,也就是 4k ,如果有需要才会扩充,最大就是上面说的 1M - 8k (oneWay 就减半)。

其实还有一个打包需要占用空间,所以真正可用的空间还不到 1M - 8k

补充视频里面有代码的详细讲解,不过目前面试用不到,先不看

谢谢你的鼓励