概述
IPC:Inter-Proscess Communication,意为进程间的通信。在Android平台,跨进程通信的方式有好几种,分别是:管道,消息队列,共享内存,信号量,socket以及Binder等。
同时这也是Linux的跨进程通信方式。但是今天,主要分析的是Binder机制。
Binder
Binder机制是什么?
- 从机制的角度来讲,Binder是一种跨进程通信(IPC)的方式,即Binder模型机制。作用是在Android中实现跨进程通信。
- 从组成角度来说,Binder是一种虚拟的物理设备驱动。作用是连接Client进程,Server进程和Service Manager进程。
- 从源码的角度来讲,Binder是一个类,实现了IBinder接口
1
2public class Binder implements IBinder {
}
Binder的优点
对于Linux而言,已经有了像管道,消息队列,内存共享等跨进程通信的方式,为什么还会出现Binder机制?
首先了解Linux的基础知识,
在Linux中,一个进程空间分为用户空间和内核空间。
用户空间
数据不可共享
内核空间
数据可以共享,且所有进程共享内核空间。
了解上面的用户空间和内核空间的特性,大概可以猜出,利用进程共享内核空间这一特性,要想进行进程间的数据传递,可以将一进程的用户空间里的数据复制进内核空间,让二进程从内核空间将数据复制进自己的用户空间,即可实现进程的数据传递。
在linux中,空间数据交互的函数有:
- copy_from_user():将用户空间的数据拷贝到内核空间
- copy_to_user():将内核空间的数据拷贝到用户空间
所以利用上面两个函数能实现数据的复制传递。如下图:
可以看出,上面数据的传递需要进行两次的数据复制。这是传统的跨进程通信,但是Binder机制只需一次复制。
Binder机制原理
- Binder驱动在内核空间创建接收缓存区
- 地址映射:将内核缓存区,接收进程的用户空间同时映射Binder创建的同一个共享接收缓存区中。
- 发送进程通过copy_from_user()将用户空间的数据拷贝到内核空间的内缓存区中。
- 内核空间和接收进程的用户空间地址存在映射关系(同时映射到Binder创建的接收缓存区)。相对于也将数据发送到了接收进程的用户空间,即实现了进程间的通信。过程只进行了一次数据复制。
示意图:
可以看到只有一次数据复制,使得传递效率变高。
多进程引发的问题
在Android中,多进程会引发以下几个问题:
- 静态成员和单例失效:每个进程保持各自的静态成员和单例,相互独立。
- 线程同步机制失效:每个进程有自己的线程锁。
- SharedPreferences可靠性下降:不支持并发写,会出现脏数据。
- Application多次创建:不同进程跑在不同虚拟机,每个虚拟机启动会创建自己的Application,自定义Application时生命周期会混乱。
总结
不同进程间的交互在Android中会以客户端进程和服务进程表现出来,即C/S模式。Binder连接了Service进程和Client进程和ServieManager进程。
Client进程,Service进程和ServiceManager进程属于上述所说的进程空间的用户空间,是不能进行通信的。而Binder属于进程空间的内核空间,可以采用复制和映射的形式进行通信的。如下图:
关于利用Binder跨进程的如何具体实现(AIDL),可参看《IPC的实现:AIDL》