Android 进程间的通信

参考资料:
几种进程通信方式的对比总结
Android Binder 机制(一) Binder 的设计和框架
Android 面试收集录14 Android 进程间通信方式
一篇文章了解相见恨晚的 Android Binder 进程间通讯机制
Broadcast、AIDL、ContentProvider、Messager的区别和适用场景

目录

  • Android 进程间的通信
    • 目录
    • Binder 通讯机制
      • 什么是 Binder
      • Binder 架构
        • Binder 模型
        • Binder 通信原理
          • Client 和 Server
          • Binder 驱动
          • ServiceManager
          • Client 获取远程服务代理
          • 总的流程
    • AIDL
    • Messenger
    • ContentProvider
    • 文件
    • Socket
    • 如何选择

Binder 通讯机制

什么是 Binder

Binder 是 Android 系统中进程间通讯( IPC )的一种方式,也是 Android 系统中最重要的特性之一。Android 中的四大组件 Activity , Service , Broadcast , ContentProvider ,不同的 App 等都运行在不同的进程中,它是这些进程间通讯的桥梁。正如其名“粘合剂”一样,它把系统中各个组件粘合到了一起,是各个组件的桥梁。

Binder 架构

Binder 模型

Android 面试经验 - Android 进程间的通信_第1张图片

Binder 通信采用 C-S 架构,它包含 Client、 Server、 ServiceManager 以及 Binder 驱动这四个组件,它们的工作就是让 Client 和 Server 进行通信。

Binder 通信原理

Client 和 Server

如果 C-S 架构中的 Client 和 Server 属于同一进程的话,那么 Client 和 Server 之间的通信就非常容易。只需要在 Client 端先获取相应的 Server 端对象,再通过 Server 对象调用 Server 的相应接口即可。

但是,Binder 机制中涉及到的 Client 和 Server 是位于不同的进程中的,这就意味着,不可能直接获取到 Server 对象。

怎么办呢?

解决方法是为 Client 提供一个 Server 的远程服务作为代理。Client 要和 Server 通信时,只需要调用该代理的相应接口,其作用就相当于直接拿到 Server 的对象。

那么这个远程服务是如何帮 Client 代理的呢?

首先我们要知道 Linux 系统下的内存划分为用户空间内核空间

用户空间和内核空间

用户空间是应用程序的运行空间,内核空间是 Linux 内核的运行空间。为了安全,它们是隔离的,即使用户的程序崩溃了,内核也不受影响。

用户空间不能直接调用系统资源,必须通过系统接口,才能向内核发出指令,而内核空间可以执行任意命令,调用系统的一切资源。

由于应用程序都运行在用户空间,并且互相隔离,所以如果不同的应用程序之间需要通信,则必须通过内核空间进行中转。这就好比以前不同地方的两个人通信需要借助邮局来传递信件一样。

在上述 Binder 的四个组件中,Client 和 Server 位于用户空间,而 Binder 驱动位于内核空间,所以 Binder 驱动就扮演了“邮局”这样一个负责中转的角色。

Binder 驱动

在 Binder 驱动中,存在着一个个 Binder 实体,每一个 Binder 实体都保存了对应的 Server 的信息。

ServiceManager

ServiceManager 是一个特殊的 Server,负责 Server 的注册与查询,它在系统开机时启动。

ServiceManager 中有一棵红黑树,用于存放 Binder 驱动中 Binder 实体的引用。Server 注册时,Binder 驱动会新建一个 Binder 实体,并在这棵树中添加该实体的引用。Server 的查询时,便是在这棵树上进行的。

当应用程序启动时,ServiceManager 会和 Binder 驱动进行通信,告诉 Binder 驱动它是服务管理者。随后,Binder 驱动会为 ServiceManager 创建对应 Binder 实体,并将该 Binder 实体设为全局变量。方便后面 Client 和 Server 与 ServiceManager 进行通信。

Client 获取远程服务代理

上面说到,Client 要和 Server 通信,需要通过 Server 的远程服务作为代理。那么 Client 是如何获取到 Server 的远程服务的呢?

Client 首先会向 Binder 驱动发起获取服务的请求。Binder驱动在收到该请求之后会将该请求转发给 ServiceManager 进程。随后,ServiceManager 会根据 Client 提供的 Server 的服务名,从红黑树中找到对应 Server 的引用信息,并将其返回给 Client 。

Client 收到 Server 对应的 Binder 引用信息之后,就根据该 Binder 引用信息创建一个与 Server 对应的远程服务,这个远程服务就是我们所说的代理。

Client 通过调用该远程服务的接口,就相当于在调用 Server 的服务接口一样。因为 Client 调用该 Server 的远程服务接口时,该远程服务会通过 Binder 驱动的 Binder 实体连接到真正的 Server 进行交互,从而执行相应的动作。

总的流程

1.应用启动
ServiceManager -> Binder 驱动创建全局的 Binder 实体

2.Server注册
Server -> Binder 驱动创建 Binder 实体 -> ServiceManager 添加 Binder 引用

3.Client 与 Server 通信

Client -> Server 的远程服务 -> Binder 实体 -> Server

Android 面试经验 - Android 进程间的通信_第2张图片

AIDL

Android Framework 层对 Binder 使用的封装,方便开发者使用。

Server 端每收到一个请求,就会启动一个线程去响应。

Client 端获取返回值是同步的。

Messenger

AIDL 的进一步封装,以串行的方式处理客户端发来的消息。

Server 端收到的请求都会放在 Handler 的 MessageQueue 里面。

Client 端获取返回值是异步的。

ContentProvider

AIDL 的封装,可以实现在应用程序中共享数据,并提供增删改查的功能。

文件

通过文件共享信息,如 SharedPreferences 。

通过序列化对象到文件中,从文件中反序列化恢复对象。

Socket

通过 socket 实现一对一的网络传输。

如何选择

Android 面试经验 - Android 进程间的通信_第3张图片

  • 只有允许不同应用的客户端用 IPC 方式调用远程方法,并且想要在服务中处理多线程时,才有必要使用 AIDL
  • 如果需要调用远程方法,但不需要处理并发 IPC,就应该通过实现一个 Binder 创建接口
  • 如果您想执行 IPC,但只是传递数据,不涉及方法调用,也不需要高并发,就使用 Messenger 来实现接口
  • 如果需要处理一对多的进程间数据共享(主要是数据的 CRUD),就使用 ContentProvider
  • 如果要实现一对多的并发实时通信,就使用 Socket

更多相关文章

  1. 【Unity3D】Unity3D与Android的交互通信(Android Studio3.0版本)
  2. Android进程间通信--消息机制及IPC机制实现
  3. Android 8.1 zygote创建新应用进程
  4. android杀进程方法
  5. 利用oom_adj提高Application所在进程的优先级
  6. android中线程进程模型
  7. Android 上 Https 双向通信— 深入理解KeyManager 和 TrustManag
  8. Android ContentProvider 多进程multiprocess 详解
  9. 【Android】socket通信【客户端访问】

随机推荐

  1. android 关于google刘海屏的解决方案
  2. Android中gravity与layout_gravity的区别
  3. Android开发——控件基础(五)RadioButton组
  4. android中的六大布局
  5. Android腾讯微薄客户端开发教程汇总
  6. android 关于google刘海屏的解决方案
  7. layout_gravity与android:gravity有什么
  8. android各个文件分析
  9. android:versionCode和android:versionNa
  10. Android跨进程通信IPC之13——Binder总结