Binder
MoMo Lv5
  1. 请介绍什么是Binder机制⭐⭐⭐⭐⭐
  2. 请介绍Binder机制流程 ⭐⭐⭐⭐
  3. Binder机制需要多少次内存拷贝 ⭐⭐⭐
  4. Android有很多跨进程通信方法,为何选择Binder?⭐⭐⭐

image

Android中的跨进程方法

Binder是Android中的一种跨进程通信机制,采用服务端/客户端结构,主要包含服务端、客户端、ServiceManager、Binder驱动4大部分。

  • 共享内存: 通过共享缓冲区直接映射到各个进程的虚拟地址空间,速度快。但实现比较复杂,进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决;
  • 消息队列: 提供了一种从一个进程向另一个进程发送一个数据块的方法,但需要进行2次数据拷贝,不适合频繁或者数据量大的情况;
  • 管道: 分为有名/无名管道,在创建时分配一个page大小的内存,缓存区大小比较有限;
  • 信号量: 一般作为一种锁机制,用于进程/线程同步;
  • 信号: 更适合作为进程中断控制,而非数据交换;
  • Socket/LocalSocket: 允许位于同一主机(计算机)或使用网络连接起来的不同主机上的应用程序之间交换数据;
  • Binder: Binder是Android中的一种跨进程通信机制;
  • 匿名共享内存: 在Android系统中,提供了独特的匿名共享内存子系统Ashmem(Anonymous Shared Memory),它利用了Linux的 tmpfs文件系统(一种可以基于RAM或是SWAP的高速文件系统)来实现不同进程间的内存共享。有两个特点:
    • 能够辅助内存管理系统来有效地管理不再使用的内存块;
    • 通过Binder进程间通信机制来实现进程间的内存共享;
  • File: 通过文件进行多进程通信用法简单,但不适合高并发情况;
  • ContentProvider: Android四大组件之一,常用于进程间数据共享,特别是一对多的情况,不过受限于AIDL;
  • Bundle: 很常见也很常用,但只能传输Bundle支持的数据类型,同样不适合大量数据的传输;

为何要使用Binder

使用Binder的理由可以总结为性能、安全、稳定几个方面:

  • 性能:管道、消息队列、Socket都需要2次数据拷贝(即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区),而Binder只要1次(可见第3节分析),且Binder相对Socket方法也更加高效,Socket主要用于跨网络的进程间通讯,传输的效率比较低。当然共享内存1次数据拷贝都不需要,因此就性能而言,共享内存高于Binder;
  • 安全:Android系统为每个应用都分配各自的UID以鉴别不同进程。Binder会验证权限,鉴定UID/PID来验证身份,保证了进程通信的安全性;
  • 稳定:共享内存1次数据拷贝都不需要,但实现的方法比较复杂,并且需要做好进程同步,容易出现死锁或者资源竞争,稳定性差。而Binder基于C/S架构,客户端和服务端彼此独立,稳定性强。

因此,在Android系统的IPC方式,一般情况下都推荐使用Binder。当然,在Android源码里,上述其他IPC方法也会使用到。接下来让我们先看看传统的Linux跨进程通讯原理。

传统的Linux跨进程通讯

一个进程空间分为 用户空间 & 内核空间(Kernel),即把进程内 用户 & 内核 隔离开来

二者区别:

  • 进程间,用户空间的数据不可共享,所以用户空间 = 不可共享空间
  • 进程间,内核空间的数据可共享,所以内核空间 = 可共享空间
  • 所有进程共用1个内核空间

进程内 用户空间 & 内核空间 进行交互 需通过 系统调用,主要通过函数:

1
2
copy_from_user()  // 将用户空间的数据拷贝到内核空间
copy_to_user() // 将内核空间的数据拷贝到用户空间

image

Android是基于Linux的,以32位系统来说,在每一个Linux进程都有3G虚拟内存空间,称之为用户空间,以及1G的内核空间。其中,不同进程的用户空间是相互隔离不可直接通讯的,但是内核空间却是共享的。以进程A发送数据到进程B为例,需要经历如下步骤:

  • 进程A的内核空间开辟一块内核缓存区,通过copy_from_user()系统调用,将在用户空间的数据拷贝到内核缓存区;
  • 进程B的内核空间也开辟了一块内核缓存区,因为不同进程的内核空间共享的,此时进程B就可以通过copy_to_user()系统调用将内核缓存区的数据拷贝到自己的用户空间;

如此就完成了一次进程间通讯,上面说到的管道、消息队列都是基于这种方式,因此有两个缺点:

  1. 经历2次数据拷贝,效率较低;
  2. 进程B接收的内核缓存区无法确定开辟多大的空间合适,太大自然损耗空间,太小则可能出现拷贝不完整,因此要么开辟尽可能大的空间,要么先获取进程A发送的数据大小再开辟对应大小的空间。这两种做法要么浪费空间,要么浪费时间。
  3. image

Binder的通讯原理

a. Binder的作用是:连接两个进程,实现了mmap()系统调用,主要负责创建数据接收的缓存空间 & 管理数据接收缓存
b. 传统的跨进程通信需拷贝数据2次,但Binder机制只需1次,主要是使用到了内存映射

  1. Binder驱动:Linux有一个叫“动态内核可加载模块”的机制,因此Android系统就可以通过动态添加这个模块,让该模块链接到内核作为内核的一部分,实现用户进程通过这个内核模块作为通讯桥梁。这个模块就是“Binder驱动”。
  2. 内存映射:内存映射即经典的mmap()方法,该方法可以将进程的用户空间的一块用户内存区域A映射到内核空间B,映射后,用户内存区域A的修改都会直接反应到内核空间B,反之亦然。

以进程A发送数据到进程B为例,一次完整的Binder通讯的步骤如下:

  • Binder驱动链接到内核空间后,开辟出一个数据接收缓存区1;
  • 进程A在内核空间开辟一块内核缓存区2,接着将数据接收缓存区1和进程A的内核缓存区2做内存映射,同时再将数据接收缓存区1和进程B的用户空间中的用户内存区域3也做内存映射。如此一来,进程A的内核缓存区2的修改也会同步反映到程B的用户空间中的用户内存区域3中;
  • 进程A通过copy_from_user()系统调用,将在用户空间的数据拷贝到内核缓存区2中,此时这些数据就会同步反映到B的用户空间中的用户内存区域3中。

这样便完成了一次进程间通讯,并只有1次数据拷贝。

image

image

Binder通信模型

image

image

image

服务端、客户端、ServiceManager、Binder驱动

Binder 跨进程通信机制 模型 基于 Client - Server 模式

Binder基于服务端/客户端架构,主要包括服务端、客户端、ServiceManager、Binder驱动这4个部分。以进程A与进程B通讯为例,进程B就是客户端,进程A为服务端。其中服务端、客户端、ServiceManager运行在用户空间,只有Binder驱动运行在内核空间。ServiceManager和Binder驱动是系统提供的,服务端和客户端则由应用程序来实现。

image

image

Binder驱动

Binder驱动在系统里对应/dev/binder文件,负责进程间Binder通讯的建立。是服务端、客户端、ServiceManager这3者之间的桥梁。Binder跨进程传递、Binder引用计数管理、数据包跨进程传递等一系列操作都需要Binder提供支持。

ServiceManager

ServiceManager作用很强大,在Binder通讯中,主要作用管理服务端和客户端。系统中会有一个进程使用BINDERSETCONTEXT_MGR 命令将自己注册成 ServiceManager。此时,Binder驱动会为该ServiceManager进程在内核空间创建对应的Binder实体,这个实体可以在其他的进程通过第0号Binder引用获得。那么,其他进程都可以通过第0号引用和ServiceManager的Binder通讯有什么作用呢?

服务端向ServiceManager注册

该案例中,进程B作为服务端,可以通过第0号引用获得ServiceManager的Binder引用,通过该Binder引用和ServiceManager通讯。进程B会先创建自己的Binder实体,并起个容易记得的名字,如“进程B”,将这个Binder实体和名字一起打包,通过第0号引用通知ServiceManager注册一个名为“进程B”的Binder。此时,会由Binder驱动为进程B创建位于内核空间的Binder实体,以及ServiceManager对该Binder实体的引用,ServiceManager可以通过“进程B”这个名字找到新创建的进程B的Binder实体。

有一个叫法问题需要统一下,在进程A和进程B通讯的案例中,进程B作为服务端。但是在进程B通过第0号引用向ServiceManager注册时,进程B其实是作为“客户端”,ServiceManager是“服务端”。也就是一个进程,比如进程B可能是提供服务的服务端,但至少对于ServiceManager这个进程来说,进程B仍然是一个“客户端“。

客户端获取服务端Binder引用

作为服务端的进程B已经向ServiceManager注册好,此时作为客户端的进程A也可以通过第0号引用,向ServiceManager请求访问名字叫做“进程B”的Binder引用。ServiceManager通过客户端发送过来的名字,查到对应的进程B的Binder引用回复给进程A。进程A就可以通过该Binder引用和进程B通讯了。

到此为止,Binder驱动为作为服务端的进程B创建了位于内核空间的Binder实体,同时ServiceManager拥有该Binder实体的引用,作为客户端的进程A也拥有该Binder实体的引用。如果接下来有进程C也作为客户端请求进程B的Binder,则最后进程C也会拥有进程B的Binder实体的引用。

Binder通讯中的代理模式

上面说到作为客户端的进程A通过Binder驱动获取到了作为服务端的进程B的Binder引用,这个Binder引用更准确来说应该称为BinderProxy,也就是进程A获取到的是进程B的Binder代理对象,通过该Binder代理对象,进程A可以调用进程B提供的方法。

当然,因为进程A和B毕竟存在进程边界。所以进程A获取到的进程B的Binder代理对象并非可以直接使用进程B提供的方法。进程A只是调用方法时,把请求参数打包成Parcel对象,通过Binder代理对象发给Binder驱动,Binder驱动看到这个Binder代理对象是进程B的Binder代理,就会通知进程B解包Parcel对象,使用传入的请求参数,调用对应的方法,最后把进程B执行完的结果返回给进程A。但对于进程A来说,就像是直接调用了进程B的方法。

A 进程想要 B 进程中某个对象(object)是如何实现的呢?毕竟它们分属不同的进程,A 进程 没法直接使用 B 进程中的 object。

跨进程通信的过程都有 Binder 驱动的参与,因此在数据流经 Binder 驱动的时候驱动会对数据做一层转换。

当 A 进程想要获取 B 进程中的 object 时,驱动并不会真的把 object 返回给 A,而是返回了一个跟 object 看起来一模一样的代理对象 objectProxy,这个 objectProxy 具有和 object 一模一样的方法,但是这些方法并没有 B 进程中 object 对象那些方法的能力,这些方法只需要把把请求参数交给驱动即可。对于 A 进程来说和直接调用 object 中的方法是一样的。

当 Binder 驱动接收到 A 进程的消息后,发现这是个 objectProxy 就去查询自己维护的表单,一查发现这是 B 进程 object 的代理对象。于是就会去通知 B 进程调用 object 的方法,并要求 B 进程把返回结果发给自己。当驱动拿到 B 进程的返回结果后就会转发给 A 进程,一次通信就完成了。

image

好多Binder分不清?

在上面说的服务端、客户端、ServiceManager、Binder驱动这4个部分,他们的代表都是“Binder”,Binder一词出现多次,可能有部分同学觉得有点乱,现在统一理一遍:

  • 通常意义:通常我们说“Binder”,就是指Android里面的一种跨进程通讯机制;
  • 服务端进程:对服务端进程来说,“Binder”指服务端进程创建的自己的Binder本地对象;
  • 客户单进程:对客户端进程来说,“Binder”指客户端进程从ServiceManager拿到的服务端进程里的Binder本地对象,在客户端进程的一个Binder代理对象;
  • 传输过程:在跨进程传输过程中,“Binder”是可以进行跨进程传递的对象;Binder驱动会对具有跨进程传递能力的对象做特殊处理,会自动完成代理对象和本地对象的转换。

Binder通讯流程

综上,服务端、客户端、ServiceManager、Binder驱动之间的通讯过程大致如下:

  • 系统会有一个进程使用BINDER_SET_CONTEXT_MGR命令通过 Binder 驱动将自己注册成 ServiceManager;
  • Server 通过驱动向 ServiceManager 中注册 Binder(Server 中的 Binder 实体),表明可以对外提供服务。驱动为这个 Binder 创建位于内核中的实体节点以及 ServiceManager 对实体的引用,将名字以及新建的引用打包传给 ServiceManager,ServiceManger 将其填入查找表。
  • 客户端通过名字在Binder驱动的帮助下,从ServiceManager获取到服务端内核空间的Binder实体的引用,即服务端的Binder代理,通过这个代理就可以实现和服务端的通讯。

如下图所示:

image

看一个跨进程调用系统服务的demo:

1
2
3
4
5
6
//获取WindowManager服务引用
WindowManager wm = (WindowManager) getSystemService(getApplication().WINDOW_SERVICE); //1
//布局参数layoutParams相关设置略...
View view = LayoutInflater.from(getApplication()).inflate(R.layout.float_layout, null);
//添加view
wm.addView(view, layoutParams);

系统开机流程中,会提前注册一系列系统服务,如WindowManager,一个用于管理窗口的系统服务。我们在[注释1]通过传入名字,从ServiceManager获取到WindowManager这个服务的本地代理,也就是wm变量,通过wm代理就可以远程调用WindowManager服务进程里提供的addView()方法。

Binder 的优势

跨进程通信高效性

数据拷贝优化

在传统的跨进程通信方式(如管道、消息队列等)中,数据需要在用户空间和内核空间之间进行多次拷贝。例如,使用管道通信时,发送方将数据从用户空间拷贝到内核空间的管道缓冲区,接收方再从内核空间拷贝到自己的用户空间。而 Binder 采用了一种优化的数据拷贝机制。当进行跨进程通信时,Binder 驱动只需要进行一次数据拷贝。它使用了内存映射(mmap)技术,将内核空间与接收进程的用户空间建立映射关系。这样,数据可以直接从发送进程的用户空间传递到接收进程的用户空间,减少了数据拷贝的次数,从而提高了通信效率。

假设要传输一个较大的文件数据,在传统方式下可能因为多次拷贝导致较长的传输时间和较高的资源消耗。而 Binder 通过一次拷贝就能完成数据传输,大大缩短了传输时间,尤其在处理大量数据的跨进程通信场景中,优势更加明显。

通信开销小

Binder 的通信协议相对简单。它基于消息传递机制,每个通信事务都由一个或多个命令(Command)组成,这些命令被封装在一个事务(Transaction)中。与其他复杂的跨进程通信协议相比,Binder 的协议头开销较小,减少了额外的通信负担。例如,在一些基于网络协议的跨进程通信方式中,协议头可能包含较多的网络相关信息,如 IP 地址、端口号、协议版本等,这些信息在每次通信时都需要传输和解析,增加了通信开销。而 Binder 主要关注进程间的消息传递,协议设计更简洁,使得通信效率更高。

面向对象的接口设计

接口定义清晰

Binder 使用接口(Interface)来定义跨进程通信的服务。这种方式使得服务的提供方和使用方可以通过清晰的接口定义来明确双方的职责和通信内容。例如,一个提供音乐播放服务的进程可以定义一个名为 IMusicPlayerService 的接口,其中包含 play、pause、stop 等方法来控制音乐播放。使用音乐播放服务的进程只需要通过这个接口来调用相应的方法,就像在本地调用一个普通的对象方法一样,而不需要关心服务内部的实现细节。这种面向对象的接口设计提高了代码的可读性和可维护性,使得跨进程通信的服务更容易被理解和使用。

实现多进程服务的灵活性

可以方便地在不同进程中实现同一个接口。

例如,一个应用可能有多个进程,其中一个进程负责数据下载,另一个进程负责数据处理。通过定义一个公共的接口,如 IDataService,数据下载进程可以实现这个接口来提供下载服务,数据处理进程可以通过这个接口来获取下载好的数据进行处理。这种方式使得应用可以根据功能和性能的需求,灵活地将服务分布在不同的进程中,同时保持接口的一致性,方便不同进程之间的协作。

Binder 的安全性

进程身份验证

UID 和 PID 检查

Binder 机制在通信过程中会对进程的身份进行验证。在 Android 系统中,每个进程都有一个唯一的用户 ID(UID)和进程 ID(PID)。当一个进程尝试与另一个进程通过 Binder 进行通信时,Binder 驱动会检查发起通信的进程的 UID 和 PID。例如,系统服务进程具有特定的 UID 范围,只有具有合法 UID 和 PID 的进程才能与这些系统服务进程进行通信。如果一个恶意进程试图伪装成合法进程进行通信,由于其 UID 和 PID 不匹配,Binder 驱动会拒绝其通信请求。

以 Android 系统中的相机服务为例,只有具有合法系统权限(通过正确的 UID 和 PID 标识)的应用进程才能与相机服务进程进行通信,启动相机功能。这种基于 UID 和 PID 的检查机制有效地防止了未经授权的进程访问敏感的系统服务和资源。

在操作系统(特别是移动操作系统如 Android)环境中,UID 是一个用于区分不同应用程序(APP)的标识符。每个 APP 在安装到系统时,都会被分配一个独一无二的 UID。这个 UID 主要用于系统在多个方面对 APP 进行管理和安全控制。

分配 UID 的目的
资源管理
  1. 内存隔离
    不同 UID 的 APP 在内存使用上是相互隔离的。系统通过 UID 来划分每个 APP 的内存空间,这样可以防止一个 APP 错误地访问或修改其他 APP 的内存数据。例如,当 APP A 和 APP B 具有不同的 UID 时,它们在内存中的数据存储区域是由系统严格划分的。APP A 无法直接访问 APP B 的内存空间,从而保证了每个 APP 的数据安全性和稳定性。

  2. 进程管理
    在进程层面,UID 也起到了关键作用。系统可以根据 UID 来对 APP 的进程进行调度和管理。例如,系统可以限制每个 UID 对应的进程数量,避免某个 APP 过度占用系统资源。同时,当系统需要回收内存或其他资源时,也可以根据 UID 来优先处理低优先级或长时间未使用的 APP 进程。

安全与权限控制
  1. 权限分配
    UID 是权限分配的重要依据。当一个 APP 请求某些系统权限(如访问摄像头、读取通讯录等)时,系统会根据该 APP 的 UID 以及其在安装时声明的权限来决定是否授予。例如,一个具有普通用户 UID 的 APP 如果没有在安装时声明访问短信权限,系统将不允许它访问短信相关的功能。这种基于 UID 的权限控制机制可以有效地防止恶意 APP 随意获取用户敏感信息。

  2. 防止恶意攻击
    通过 UID 的区分,系统可以识别并阻止恶意 APP 的攻击行为。例如,恶意软件通常会试图通过非法手段获取其他 APP 的资源或者干扰其他 APP 的正常运行。由于系统根据 UID 对 APP 进行了严格的隔离和权限控制,恶意软件很难突破这种安全机制去攻击其他合法 APP。

实名和匿名 UID 支持

实名 UID
定义与应用场景

实名 UID 是指与 APP 开发者或所有者的真实身份相关联的 UID。在一些应用场景下,如企业级应用、金融类应用等,需要对 APP 的来源和责任主体进行明确的追溯。对于这些 APP,系统会为其分配实名 UID。这个实名 UID 可以与开发者的企业信息、开发者账号等相关联。例如,银行推出的手机银行 APP,其 UID 会与银行的企业身份信息相关联。

安全与监管优势
  • 安全方面: 当出现安全问题(如数据泄露、恶意攻击等)时,系统可以通过实名 UID 快速定位到责任主体,即 APP 的开发者或所有者。这样可以促使开发者更加重视 APP 的安全性,采取有效的安全措施。例如,如果银行 APP 发生安全漏洞导致用户资金损失,监管部门可以通过实名 UID 追溯到银行,要求其承担相应的责任并采取措施修复漏洞。

  • 监管方面: 对于应用市场和监管机构来说,实名 UID 有助于对 APP 进行更严格的监管。监管机构可以根据实名 UID 来审核 APP 的合法性、合规性以及是否符合相关行业标准。例如,医疗类 APP 需要符合医疗行业的相关法规和标准,通过实名 UID 可以方便监管机构对这些 APP 进行监管,确保其提供的医疗服务是安全可靠的。

匿名 UID
定义与应用场景

匿名 UID 是指不直接与 APP 开发者或所有者的真实身份相关联的 UID。这种 UID 主要用于一些对隐私要求较高或者不需要明确责任主体的 APP。例如,一些小型的工具类 APP(如简单的计算器、日历等)或者一些个人开发者制作的创意类 APP,用户可能更关注隐私保护,不希望自己的使用行为与个人身份信息过多关联。对于这些 APP,系统可以为其分配匿名 UID。

隐私保护优势
  • 用户隐私: 匿名 UID 可以保护用户的隐私。当用户使用这些 APP 时,其行为数据不会直接与 APP 开发者的真实身份相关联。这样可以防止用户的使用习惯、个人偏好等信息被开发者滥用。例如,用户使用匿名 UID 的日历 APP 记录个人日程安排,开发者无法通过 UID 获取用户的真实身份信息,从而保护了用户的隐私。

  • 开发者隐私: 对于一些个人开发者或者小型开发团队来说,匿名 UID 也可以保护他们的隐私。他们可能不希望自己的开发行为和个人信息被过度暴露,尤其是在开发一些实验性或者非商业性较强的 APP 时。通过使用匿名 UID,他们可以在一定程度上保护自己的隐私,同时仍然能够将 APP 发布到应用市场供用户使用。

UID 分配机制的实现

系统层面的分配过程
安装时分配

当用户在设备上安装一个 APP 时,系统会自动为其分配 UID。这个分配过程通常是由操作系统的安装程序或者应用商店来完成。安装程序会检查系统中已有的 UID 分配情况,确保为新安装的 APP 分配一个独一无二的 UID。例如,在 Android 系统中,安装程序会查询系统的 UID 分配表,找到一个未被使用的 UID 并分配给新 APP。

基于规则的分配

UID 的分配通常遵循一定的规则。这些规则可能包括根据 APP 的类型(如系统应用、第三方应用)、所属类别(如游戏、工具、社交等)或者安装来源(如官方应用商店、第三方应用市场)等来进行分配。例如,系统应用可能会被分配在一个特定的 UID 范围,而第三方应用则在另一个范围。这种基于规则的分配方式有助于系统更好地对不同类型的 APP 进行管理和安全控制。

实名 UID 和匿名 UID 的区分实现
身份验证环节

对于实名 UID 的分配,系统会在 APP 提交审核或者注册过程中要求开发者提供真实的身份信息。这些信息可能包括企业营业执照、开发者个人身份证等。应用市场或者操作系统的开发者平台会对这些信息进行验证。只有通过验证的 APP 才会被分配实名 UID。例如,苹果的 App Store 会要求开发者提供详细的企业或个人信息,并进行严格的审核,审核通过后才会为 APP 分配与开发者身份相关的 UID。

匿名 UID 的生成

匿名 UID 的生成通常是通过系统的随机算法来实现。系统会在一个预先定义的 UID 范围内,使用随机数生成器来生成一个不与任何真实身份相关联的 UID。这个 UID 只用于区分 APP,而不包含任何关于开发者身份的信息。例如,在某些开源的移动操作系统中,当用户安装一个匿名 UID 的 APP 时,系统会从一个匿名 UID 池中随机选择一个未被使用的 UID 分配给该 APP。

权限检查

除了 UID 和 PID 检查外,Binder 还会结合权限机制来确保通信的安全性。Android 系统为每个应用和服务定义了不同的权限,这些权限可以在应用的清单文件(AndroidManifest.xml)中声明。当一个进程通过 Binder 访问另一个进程提供的服务时,系统会检查发起访问的进程是否具有相应的权限。例如,一个应用如果要访问用户联系人信息的服务,它必须在清单文件中声明相应的联系人读取权限。如果没有这个权限,即使进程的 UID 和 PID 是合法的,Binder 也会阻止其访问联系人服务,从而保护用户的隐私和数据安全。

通信数据保护

数据完整性检查

Binder 在数据传输过程中会进行完整性检查。它通过在数据包头中添加校验和(Checksum)等信息来确保数据在传输过程中没有被篡改。当接收方收到数据时,会验证校验和是否正确。如果校验和不匹配,说明数据可能在传输过程中被修改,接收方会丢弃这个数据并可能采取相应的安全措施,如记录错误信息、通知相关安全模块等。这种数据完整性检查机制可以防止中间人攻击,确保跨进程通信数据的真实性和可靠性。

数据加密

在一些高安全需求的场景下,Binder 支持数据加密。例如,在涉及金融交易等敏感信息的跨进程通信中,应用可以通过加密算法对传输的数据进行加密。Binder 提供了相应的接口和机制,使得数据在发送方进行加密,在接收方进行解密,保证数据在传输过程中的保密性。通过加密技术,即使数据在传输过程中被拦截,攻击者也无法获取其中的敏感信息,进一步提高了跨进程通信的安全性。

Binder源码分析

Binder系列

总结

从进程间通信的角度看,Binder 是一种进程间通信的机制;
从 Server 进程的角度看,Binder 指的是 Server 中的 Binder 实体对象;
从 Client 进程的角度看,Binder 指的是对 Binder 代理对象,是 Binder 实体对象的一个远程代理
从传输过程的角度看,Binder 是一个可以跨进程传输的对象;Binder 驱动会对这个跨越进程边界的对象对一点点特殊处理,自动完成代理对象和本地对象之间的转换。

image

image

Powered by Hexo & Theme Keep
Unique Visitor Page View