Binder进程间通信原理

Android app常见使用多进程的场景

1.吃大内存的模块,如地图模块、大图浏览、webview等,Android对内存的限制是针对于进程的。
2.调用系统服务,比如电话,闹钟

Android app要用多进程的两个原因:

1.突破虚拟机分配进程的运行内存限制。
Android虚拟机分配给每个进程的内存是有限的(如16M,32M,64M,96M等等),可以在新的进程中去执行,避免主进程OOM
2.提高app稳定性,单个进程崩溃不影响整个app
如微信的小程序进程崩溃后,微信依然可以正常运行。
3.对内存更可控,通过主动释放进程,减小系统压力,提高系统流畅性
在接收到系统发出的trimMemory(int level)里主动释放重要级低的进程。

公路-内核空间
快递-进程间的通信机制

Linux现有的进程间通信机制有哪些

管道(Pipe):在创建时分配一个page大小的内存,缓存区大小比较有限;
消息队列(Message):信息复制两次,额外的CPU消耗;不适合频繁或信息量大的通信;
共享内存(Share Memory):无须复制,共享缓冲区直接附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决。
套接字(Socket):作为更通用的接口,传输效率低,主要用于不同机器或跨网络的通信。
信号量(Semaphore):常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此主要作为进程间以及同一进程内不同线程之间的同步手段。

Android为什么要新增Binder机制,相比于其他进程间通信机制的优点

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

AIDL作用:生成Binder代码

Binder进程通信原理

客户端通过调用bindService可以拿到系统返回的服务端的IBinder对象,客户端通过这个IBinder对象就可以像调用普通方法一样调用另外一个进程(服务端)的方法

调用bindService()执行的流程
在这里插入图片描述

ServiceManager是系统服务,在系统进程(service_manager进程)
ActivityManagerService是系统服务,在系统进程(system_server进程)

Linux的基础知识

进程空间划分

1.一个进程空间分为 用户空间(User space) 和 内核空间(Kernel space)。

扫描二维码关注公众号,回复: 10047012 查看本文章

2.二者区别:
进程间,用户空间的数据不可共享,所以,用户空间 = 不可共享空间
进程间,内核空间的数据可共享,所以,内核空间 = 可共享空间,所有进程共用1个内核空间

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

  • copy_from_user():将用户空间的数据拷贝到内核空间
  • copy_to_user():将内核空间的数据拷贝到用户空间

在这里插入图片描述

进程隔离和跨进程通信(IPC)

进程隔离

为了保证安全性和独立性,一个进程不能直接操作或者访问另一个进程,即Android的进程是相互独立、隔离的。

跨进程通信(IPC)

即进程间需进行数据交互、通信

跨进程通信的基本原理

传统的跨进程通信:
在这里插入图片描述

而Binder机制则是:使用Binder连接两个进程,实现了mmap()系统调用,主要负责创建数据接收缓存区 ,并且管理该数据接收缓存区。

传统的跨进程通信需拷贝数据2次,但Binder机制只需1次,主要是使用到了内存映射,具体下面会详细说明。

内存映射

内存映射原理可参考:内存映射(Memory Map)

Binder机制的模型

模型原理图

Binder跨进程通信机制的模型, 基于 Client - Server 模式
在这里插入图片描述

模型的组成角色说明

在这里插入图片描述

此处重点讲解 Binder驱动的作用和原理

Binder驱动简介

在这里插入图片描述

Binder驱动原理

在这里插入图片描述
关于内存映射可以参考:内存映射(Memory Map)

模型原理的步骤说明

在这里插入图片描述

额外说明

1.Client进程、Server进程 和 Service Manager 进程之间的交互都必须通过Binder驱动(使用 open 和 ioctl文件操作函数),而非直接交互。

原因:

  1. Client进程、Server进程 和 Service Manager进程属于进程空间的用户空间,不可进行进程间交互。
  2. Binder驱动属于进程空间的内核空间,可进行进程间以及进程内交互。

所以,原理图可表示为以下(虚线表示并非直接交互):
在这里插入图片描述

2: Binder驱动和Service Manager进程属于Android基础架构(即系统已经实现好了);而Client 进程 和 Server 进程属于Android应用层(需要开发者自己实现)

所以,在进行跨进程通信时,开发者只需自定义Client 和 Server 进程,并显式使用上述3个步骤,最终借助 Android的基本架构功能就可完成进程间通信。
在这里插入图片描述

3:Binder请求的线程管理

Server进程会创建很多线程来处理Binder请求。
Binder模型的线程管理采用Binder驱动的线程池,并由Binder驱动自身进行管理,而不是由Server进程来管理的。
一个进程的Binder线程数默认最大是16,超过的请求会被阻塞等待空闲的Binder线程。所以,在进程间通信时处理并发问题时,如使用ContentProvider时,它的CRUD(创建、检索、更新和删除)方法只能同时有16个线程同时工作。

下面,我将通过一个实例,分析Binder跨进程通信机制模型在Android中的具体代码实现方式

Binder机制在Android中的具体实现

bindService(intent, serviceConnection, BIND_AUTO_CREATE);

ContextImpl.bindServiceCommon()

ActivityManagerService. bindService()

ActiveServices.bindServiceLocked()

Binder机制的优点

参考:

Android跨进程通信:图文详解 Binder机制 原理
图文详解 Android Binder跨进程通信的原理

Android Bander设计与实现 - 设计篇
面试必备:Binder进程通信原理
Android Binder机制原理(史上最强理解,没有之一)
android binder 基础实例及解析(一)

Android Binder——通过AIDL探究Binder

Binder机制

Android Binder 原理解析

Binder 进程间通信机制详解(Java 和 JNI 篇)

https://www.androidos.net.cn/android/9.0.0_r8/xref/frameworks/base/core/java/android/app/ContextImpl.java
https://www.androidos.net.cn/android/9.0.0_r8/xref/frameworks/base/core/java/android/app/ActivityManager.java
https://www.androidos.net.cn/android/9.0.0_r8/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
https://www.androidos.net.cn/android/9.0.0_r8/xref/frameworks/base/core/java/android/os/ServiceManager.java

https://www.androidos.net.cn/android/9.0.0_r8/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

发布了535 篇原创文章 · 获赞 94 · 访问量 74万+

猜你喜欢

转载自blog.csdn.net/yzpbright/article/details/104881378