网站首页 > 文章精选 正文
跨进程通信的几种方式
- 文件共享:不同进程访问相同文件,实现线程之间数据通信,但是多个进程同时访问会出现数据一致性等问题,不适合高并发;
- MMKV: MMKV是微信团队开源的高性能 key-value组件,良好的支持Android跨进程通信;
- Socket: 通过网络的方式实现进程之前通信, 功能强大,可通过网络传输字节流,支持一对多实时并发通信,主要场景是通过网络进行数据交互;
- Binder: Android系统中大部分场景的跨进程通信实现方式都是基于Binder。
为什么需要多进程
默认情况下,一个app只会运行在一个进程中,进程名为app的包名。Android系统对每个应用进程的内存占用是有限制的,占用内存越大的进程,被系统杀死的可能性就越大。使用多进程可以减少主进程占用的内存,避免OOM问题,降低应用退到后台被系统杀死的概率。
实现一些特殊功能
比如可以实现推送进程,使得主进程退出后,能离线完成消息推送服务。还可以实现守护进程,来唤醒主进程达到保护目的。还可以实现监控进程专门负责上报bug,进而提升用户体验。还有腾讯开源的即时通讯mars,也是将通信核心放在独立进程中,用于更好地保持app的存活率。
多进程产生的问题
- Application的重复创建
创建新的进程时会创建新的Application对象,而我们通常在Application的onCreate方法中只是完成一些全局的初始化操作,不需要多次执行。
解决思路:获取当前进程名,判断是否为主进程,只有主进程的时候才执行初始化操作
- 静态成员和单例模式完全失效
进程间的内存空间是相互隔离的,一个内存空间的值修改不影响另一个的值。
- SharedPreferences 的可靠性下降
多进程并发问题不好解决,应该尽量避免多进程并发操作,比如可以只让主进程进行对数据库的操作。
- 线程同步机制完全失效
Android IPC
IPC 即 Inter-Process Communication (进程间通信)。
Android 基于 Linux,而 Linux 出于安全考虑,不同进程间不能之间操作对方的数据,这叫做“进程隔离”。
在 Linux 系统中,通过虚拟内存机制来实现进程隔离。虚拟内存机制就是为每个进程在逻辑上分配了线性连续的内存空间,每个进程只管理自己的虚拟内存空间,因此从逻辑上实现了进程间的隔离。
每个进程的虚拟内存空间(进程空间)又被分为了用户空间和内核空间,进程只能访问自身用户空间,只有操作系统能访问内核空间。
由于进程只能访问自身用户空间,因此在传统的IPC中,发送进程需要通过copy_from_user(系统调用)将数据从自身用户空间拷贝到内核空间,再由接受进程通过copy_to_user从内核空间复拷贝到自身用户空间,共需要拷贝2次,效率十分低下。Android采用的是Binder作为IPC的机制,只需复制一次。
Binder
为什么选用Binder作为IPC的机制?
- 性能较好,管道、消息队列、Socket方式都需要2次数据拷贝,而Binder只需要1次数据拷贝,性能仅次于共享内存。
- 缺点少,Binder基于C/S架构,架构十分清晰明了,相比于内存共享,其实现方式更为简单,且无需解决同步问题。
- 安全性好,Android为每个安装好的应用程序分配了自己的UID,传统的 IPC 形式,无法识别对方的身份标识(UID/GID),而使用 Binder IPC 时,这些身份标示是跟随调用过程而自动传递的。Server 端很容易就可以知道 Client 端的身份,非常便于做安全检查。
Binder 1次拷贝的原理:
Binder IPC通信的底层原理是通过内存映射(mmap),将接收进程的用户空间映射到内核空间,有了这个映射关系,接收进程就能通过用户空间的地址获得内核空间的数据,这样只需发送进程将数据拷贝到内核空间就可完成通讯。
一次完整的Binder IPC通信:
- 在内核空间创建一个数据接收缓存区。
- 在内核空间中开辟一块内核缓存区。
- 建立接收进程和数据接受缓存区的映射关系。
- 建立内核缓存区和数据接受缓存区的映射关系。
- 发送进程调用copy_from_user() 将数据copy到内核缓存区。
AIDL
AIDL是一个缩写,全程是Android Interface Definition Language,也是android接口定义语言。准确地来说,它是用于定义客户端/服务器通信接口的一种描述语言。它其实一种IDL语言,可以拿来生成用于IPC的代码,从某种意义上说它其实是一个模板。
通过AIDL,可以让本地调用远程服务器的接口就像调用本地接口那么接单,让用户无需关注内部细节,只需要实现自己的业务逻辑接口,内部复杂的参数序列化发送、接收、客户端调用服务端的逻辑,你都不需要去关心了。
在Android process 之间不能用通常的方式去访问彼此的内存数据。他们把需要传递的数据解析成基础对象,使得系统能够识别并处理这些对象。因为这个处理过程很难写,所以Android使用AIDL来解决这个问题。
Messager
Messenger是基于消息Message的传递的一种轻量级IPC进程间通信方式(通过在一个进程中创建一个指向Handler的Messenger,并将该Messenger传递给另一个进程),当然本质就是对Binder的封装(也是通过AIDL实现的 )。通过Messenger可以让我们可以简单地在进程间直接使用Handler进行Message传递,跨进程是通过Binder(AIDL实现),而消息发送是通过Handler#sendMessage方法,而处理则是Handler#handleMessage处理的;当然除了Handler之外还可以是自定义的相关的某些IBinder接口,简而言之,Messenger的跨进程能力是由构造时关联的对象提供的。
- 上一篇: 进程间通信(一)—管道(进程间通信机制有哪些)
- 下一篇: 面试官:进程之间的通讯方式有哪些?
猜你喜欢
- 2025-03-20 超详细的Socket通信原理和实例讲解
- 2025-03-20 高并发服务器epoll接口、epoll Reactor(反应堆)模型详解
- 2025-03-20 Linux 内核源代码的目录结构(linux内核源码在哪个文件夹)
- 2025-03-20 Linux之进程管理(linux进程管理器)
- 2025-03-20 Nginx之进程间通信-共享内存篇(nginx lua 共享内存)
- 2025-03-20 面试官:进程之间的通讯方式有哪些?
- 2025-03-20 进程间通信(一)—管道(进程间通信机制有哪些)
- 2025-03-20 进程间通信(五)—信号(进程间通信的概念)
- 2025-03-20 linux进程通信方式对比(linux端口被哪个进程占用)
- 2025-03-20 如何在Linux下的进行多进程编程(初步)
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 稳压管的稳压区是工作在什么区 (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)