文章目录

前言一、什么是多进程二、为什么要使用多进程三.进程间通信(IPC)四.Binder机制五.各种IPC机制的对比总结

前言

Android 的binder机制在面试的时候经常被问到,说明它对咱们android开发非常的重要,咱们Android的系统中很多地方都使用了binder的通信,而说到binder,咱们就不得不提进程间的通信(IPC),那为什么需要进程间的通信呢?进程间的通信有啥好处和优势?读完本篇文章,相信你会得到答案。

一、什么是多进程

这个比较简单,我们大家都知道操作系统在最初的时候是单进程的,也就是一个操作系统上面只能跑一个进程。到后面随着技术的发展,所以有了多进程。在使用的android手机的时候,你是不是既可以打开QQ,同时还能听着音乐,还能接收微信的消息推送…QQ,微信,音乐这些都是不同的进程,这些进程的用户空间互不干扰,就比如咱们使用QQ,不可给微信的好友发消息吧,在音乐的app中也不能去删除QQ中的好友吧,也就是他们之间是独立的。他们是运行在操作系统上的多个独立的进程

二、为什么要使用多进程

在Android系统中,虚拟机分配给每一个进程的运行内存是有限制的,LMK(low memory killer)会优先回收资源占用较多的进程,这就导致了咱们的应用如果占用的内存过大的话,当内存不足的时候可能会被系统优先杀死。假如咱们使用多个进程的话,将一个应用进程所需要的内存,分一部分到另一个应用进程,然后两个进程使用进程间通信的方式通信,将一个应用的功能分再两个应用进程上完成。其实,使用多进程不止这些好处,还有如下的好处:

突破进程内存限制,如图库这样的应用占用内存过多,就可以分解成多个进程功能稳定性提高。类似于推送这类需要进程保活的场景,独立的通信进程可以保持长链接的稳定性规避系统内存泄露,在实现webview的时候咱们经常会有很多内存泄露的问题,咱们可以将webview相关的功能放到独立的进程中,这样webView的内存泄露也不会影响的到主应用隔离风险,我们可以用两个进程来维护app开发,一个主app进程,另一个是副app进程,咱们可以把有风险的功能放到副APP进程中,这样的话当有风险的功能出现问题的时候不会引起主app进程的崩溃

三.进程间通信(IPC)

当我们将app的部分风险功能放到App的副进程后,当我们需要使用副进程的功能时,就需要App的主进程和副进程建立通信,就拿现在的很多相机APP来说,我们现在手机的像素越来越好,但是每一张照片占用的内存又很大,这时容易造成应用占用内存过大的情况,而且现在的手机很多支持夜景算法,夜景算法是一个多帧算法,即需要同时将多张照片通过夜景算法合成一张,这个过程如果在app进程处理很明显不合理,这时候咱们可以把它放到一个新开的进程,这个进程和相机APP的进程建立通信,当相机取到照片时就送往处理图片的进程,处理完再回调给相机APP进程。 这样的好处很明显,当用户极限操作时,比如快速拍完照,快速退出,如果都在相机APP进程处理,那么这图片还没开始处理呢,用户退出了,有可能造成丢图的情况,放在另一个进程就会极大的减少这种情况,因为放在另一个进程中,只要保证把从HAL取回来的图片数据和信息通过进程通信发给算法处理进程就可以了,相机APP进程退出不会影响图片算法处理进程的处理,因为是不同进程。所以极大的规避了风险,优化了用户体验。

因为咱们把图片的处理放到了另一个进程,但是咱们又需要将数据送到图片处理进程,需要知道另一个进程中图片处理过程中的信息。这时我们就需要用到进程间通信。也许你会问,直接通信就可以了呀,还需要单独说啥呢? 但是进程间的通信可不像咱们在应用开发过程中的线程间的通信。进程的内存分为用户空间和内核空间,内核空间的内存是共享的,而用户空间的内存是不共享的,用户空间和内核空间是隔离的,用户空间要访问内核空间,只能通过系统调用,也就是用系统提供的API 访问,系统调用的API在这里主要有两个,copy_from_ueser和copy_to_user 从上图中我们可以知道,用户空间中,内存是不共享的,无法直接进行通信,但是内核空间中内存是共享的,所以咱们要实现进程间通信可以先从进程1中将要传送的数据先拷贝到内核空间,然后再从内核空间将数据拷贝到进程2,这样就完成了进程间的通信。来张图说明下这个过程吧。 上图就是传统的IPC机制,我们可以看到虽然实现了进程间的通信,但是数据从进程1到进程2需要经过两次数据拷贝。

四.Binder机制

由于传统的IPC机制需要进行两次数据拷贝,为了提高进程间通信的效率,所以 android提出了Binder机制,只用经过一次拷贝就可以完成进程间的通信,那binder是怎么做到的呢,我们先来看看图: binder机制的一次拷贝主要靠的就是mmap(),Linux通过将一个虚拟内存区域于一个磁盘上的对象关联起来,以初始化这个虚拟内存区域的内容,整个过程称为内存映射(memory mapping),对文件进行mmap,会在进程的虚拟内存分配地址空间,建立映射关系,实现这样的映射关系后,就可以采用指针的方式读写操作这一段内存,而系统会自动回写到对应的文件磁盘上。

所以binder机制的跨进程的实现可以总结为: 进程1和进程2用户空间内存不共享,所以不能直接进行通信,但是两个进程的内核空间的进程是可以共享的,所以发送方可以通过copy_from_user()将数据拷贝到内核空间,然后内核空间和用户空间的数据接收方的虚拟地址都会映射到同一块物理地址上,这个映射技术油mmap()实现。所以当数据到了内核空间,由于内核空间和用户空间的接收方会被映射到同一块物理地址,所以也间接相当于将数据拷贝到了接收方,整个过程只涉及了一次内存拷贝。

五.各种IPC机制的对比

我们知道android是基于linux的,所以在进程间的通信机制中不只是一种,分别有管道、socket、信号、消息队列、共享内存,binder。我们常用的其实就是binder,共享内存,以及socket,让我们来看看他们的对比吧:

总结

以上就是今天要讲的内容,本文仅仅简单介绍了android进程间的通信原理及使用多进程的好处,如果想深入了解binder机制并且使用的小伙伴还需去研究binder的源码。也欢迎大家一起评论区交流讨论。下次我可能会分享android使用进程间通信的方式AIDL的实现细节。敬请期待~~~

推荐阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: