Android多进程通信之 Binder

2020-05-13  本文已影响0人  tandeneck

进程空间划分

在 Linux 中一个进程空间可以分为用户空间内核空间,不同的进程它们的用户空间数据不可共享,但是它们的内核空间的数据可共享,即所有进程共用 1 个内核空间。进程内用户空间和内核空间进行交互需通过系统调用。

为什么 Android 使用 Binder 实现多进程通信?

Android 系统时基于 Linux 内核的,Linux 已经提供了多种 IPC 方式,如下:

所以,Android 为啥又单独弄出一个 Binder 呢?主要有如下原因:

UID 和 PID 区别
PID(Process Identifier) 来源于 Linux,在进程启动的时候系统会为进程分配一个独一无二的标识,进程销毁后 PID 会被系统回收,但是在 Android 中一般不会重新分配,后面的进程 PID 会比前面的进程的大。
UID(User Identifier),同样来源于 Linux 中,但是在 Android 中不太一样,Android 最初的设计是单用户,所以 UID 并不是为了区别用户的,而是为了不同程序间进行数据共享。默认情况下每个应用都有自己一个 UID,不过可以通过在 Manifenst 文件下设置 sharedUserId 相同的 UID,同时保证签名文件一样,这样就达到共享数据的目的。

Binder 原理

直观地说,Binder 是 Android 中的一个类,它实现了 IBinder 接口;从 Android Framework 角度来说,Binder 是 ServiceManager 连接各种 Manager(ActivityManager、WindowManager...) 和相应 ManagerService 的桥梁;从 Android 应用层来说,Binder 是客户端和服务端进行通信的媒介,当 bindService 的时候,服务端会返回一个包含了服务端业务调用的 Binder 对象,通过这个 Binder 对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于 AIDL 服务。

Binder 定义了四个角色:Server,Client,ServiceManager 和 Bidner 驱动,其中 Server、Client、ServiceManager 运行于用户空间,Binder 驱动运行于内核空间。

Binder 工作原理:

当客户端发起远程请求时,由于当前线程会被挂起直至线程服务端进程返回数据,所以如果一个远程方法是很耗时的,那么不能在 UI 线程中发起此远程请求。其次,由于服务端的 Binder 方法运行在 Binder 的线程池中,所以 Binder 方法不管是否耗时都应该采用同步的方式去实现,因为它已经运行在一个线程中了。

上一篇 下一篇

猜你喜欢

热点阅读