一、IPC的说明

IPC是Inter-Process Communication的缩写,含义为进程间通信或跨进程通信,是指两个进程之间进行数据交换的过程。

IPC不是Android独有的,任何一个操作系统都需要有相应的IPC机制,比如Windows上可以通过剪贴板,管道和邮槽来进行进程间通信;Linux上可以通过命名管道、共享内容、信号量等进行进程间通信。

对于Android来说,它是一种基于Linux内核的移动操作系统,但它的进程间通信方式并不能完全继承自Linux;相反,它有自己的进程间通信方式。

在Android中可以通过Binder轻松的实现进程间通信。Android还支持Socket,通过Socket可以实现任意两个终端之间的通信,同一设备的两个进程通过Socket通信自然也是可以的。

二、Android中IPC的使用

首先,只有面对多进程的情况才需要考虑进程间通信。多进程的情况分为两种:

第一种是一个应用因为某些原因,自身需要采用多进程模式来实现,比如有些模块需要运行在单独的进程中、或者为了加大一个应用的可使用内存,需要通过多进程来获取多分内存空间。

另一种是当前应用需要向其他的应用获取数据,所以必须采用跨进程的方式来获取数据,比如使用系统的ContentProvider去查询数据。

通过给四大组件在AndroidMenifest中指定android:process属性,可以轻易地开启多进程模式。

三、Android中IPC带来的问题

两个应用共享数据:Android系统会为每个应用分配一个唯一的UID,具有相同UID的应用才能共享数据。两个应用通过ShareUID跑在同一个进程是有要求的,需要这两个应用有相同的ShareUID并且签名相同才可以。在这种情况下,他们可以相互访问对方的私有数据,比如data目录,组件信息等,不管他们是否跑在同一个进程。

Android系统为每个应用分配了一个独立的虚拟机,或者说为每一个进程都分配一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这就导致在不同的虚拟机中访问同一个对象会产生多分副本。所有运行在不同进程中的四大组件,只要它们之间需要通过内存来共享数据,都会共享失败,这也是多进程带来的主要影响。

一般来说,使用多进程会造成如下的问题:

(1)静态成员和单例模式完全失效(不同的虚拟机中访问同一个对象会产生多分副本)

(2)线程同步机制完全失效(不在同一块内存,不管是所对象还是锁全局类都无法保证线程同步)

(3)SharePreferences的可靠性下降(不支持两个进程同时写操作)

(4)Application会多次创建(因为创建新进程会分配独立虚拟机,相当于启动一个新的应用)

虽说不能直接的共享内存,但是通过跨进程通信还是可以实现数据交互。

四、Android中各种IPC方式

1、使用Bundle

四大组件中三大组件Activity、Service、Receiver都支持在Intent中传递Bundle数据。

由于Bundle实现了Parcelable接口,所以它可以很方便的在不同的进程间传输数据。当然我们传输的数据必须能够被序列化,比如基本类型、实现了Parcelable接口的对象、实现了Serializable接口的对象以及一些Android支持的特殊对象。

2、使用文件共享

两个进程通过读写同一个文件来交换数据,比如A进程把数据写入文件,B进程通过读取这个文件来获取数据。

Android系统基于Linux,使得并发读写文件可以没有限制的进行,甚至两个线程同时对文件读写操作都是允许的,尽管可能出问题,因此文件共享方式适合在对数据同步要求不高的进程间进行通信。

SharedPreferences也属于文件的一种,但是由于系统对它的读写有一定的缓存策略,即在内存中会有一份SharedPreferences文件的缓存;因此在多进程模式下,系统对它的读写就变得不可靠,会有很大几率丢失数据,不建议在进程间通信中使用SharedPreferences。

3、使用Messenger

Messenger可以理解为信使,通过它可以再不同进程中传递Message对象,在Message中放入我们需要传递的数据,就可以实现数据的进程间传递了。

Messenger是一种轻量级的IPC方案,它的底层实现是AIDL。由于它一次处理一个请求,因此在服务端不需要考虑线程同步的问题,因为服务端不存在并发执行的情形。

4、使用AIDL

AIDL是 Android Interface definition language的缩写,它是一种android内部进程通信接口的描述语言。AIDL可以处理发送到服务器端大量的并发请求(不同与Messenger的串行处理方式),也可以实现跨进程的方法调用。

在Android中使用方法:创建一个Service和一个AIDL接口,接着创建一个类继承自AIDL接口中的Stub类并实现Stub中的抽象方法,在Service的onBind方法中返回这个类的对象,然后客户端绑定服务端Service,建立连接后就可以访问远程服务器了。

5、使用ContentProvider

ContentProvider是Android中提供的专门用于不同应用间进行数据共享的方式,天生适合进程间通信。

ContentProvider的底层实现也是Binder,但是它的使用过程比AIDL简单的多,因为系统做了封装,使得无需关心细节即可轻松实现IPC。ContentProvider主要以表格的形式组织数据,和数据库很类似,但ContentProvider对底层的数据存储方式没有任何要求,既可以使用Sqlite数据库,也可以使用文件方式,甚至可以使用内存中的一个对象来存储。

6、使用Socket

Socket套接字,是网络通信中的概念,分为流式套接字和用户数据奥套接字两种,对应于网络的传输控制层中的TCP和UDP协议。

两个进程可以通过Socket来实现信息的传输,Socket本身可以支持传输任意字节流。

===选择合适的IPC方式===,如下表

名称 优点 缺点 适用场景
Bundle 简单易用 只能传输Bundle支持的数据类型 四大组件的进程间通信
文件共享 简单易用

不适合高并发场景,并且无法做到进程间

即时通信

无并发访问清醒,交换简单的数据,实时性不搞的场景
AIDL 功能强大,支持一对多并发通信,支持实时通信 使用稍复杂,需要处理好线程同步 一对多通信且有RPC需求
Messenger 功能一般,支持一对多串行通信,支持实时通信 不能很好的处理高并发情形,不支持RPC,数据通过Message进行传输,因此只能传输Bundle支持的数据类型 低并发的一对多即时通信,无RPC需求
ContentProvider

在数据源访问方面功能强大,支持一对多并发数据共享,

可通过Call方法扩展其他操作

可以理解为受约束的AICL,主要提供数据的CRUD数据 一对多的进程间数据共享
Socket 功能强大,可以通过网络传输字节流,支持一对多并发实时通信 实现细节稍微繁琐,不支持直接的RPC 网络数据交换

RPC(Remote Procedure Call,远程过程调用)是种C/S的编程模式,出于一种类比的愿望,在一台机器上运行的主程序,可以调用另一台机器上准备好的子程序。

通过RPC可以充分利用非共享内存的多处理器环境,可以简便地将你的应用分布在多台工作站上,应用程序就像运行在一个多处理器的计算机上一样。

 五、Binder介绍

Binder是Android系统进程间通信方式之一。Linux已经拥有的进程间通信IPC手段包括: 管道(Pipe)、信号(Signal)、跟踪(Trace)、插口(Socket)、报文队列(Message)、共享内存(Share Memory)和信号量(Semaphore)。

Binder框架定义了四个角色:Server,Client,ServiceManager以及Binder驱动。

其中Server,Client,ServiceManager运行于用户空间,驱动运行于内核空间。Binder就是一种把这四个组件粘合在一起的粘结剂了,其中,核心组件便是Binder驱动程序了,Service Manager提供了辅助管理的功能,Client和Server正是在Binder驱动和Service Manager提供的基础设施上,进行Client-Server之间的通信。这四个角色的关系和互联网类似:Server是服务器,Client是客户终端,ServiceManager是域名服务器(DNS),驱动是路由器。

Binder的理解:

1、从IPC角度来说,Binder是Android中的一种跨进程通信方式,该方式在Linux中没有;

2、从Android Framework角度来说,Binder是ServiceManager连接各种Manager和相应ManagerService的桥梁;

3、从Android应用层来说,Binder是客户端和服务端进行通许in的媒介,当BindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个Bind而对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务。

在Android开发中,Binder主要用在Service中,包括AIDL和Messenger,普通服务中的Binder不涉及进程间通信。

直观来讲,Binder是Android中的一个类,实现了IBinder接口。

Binder的工作机制:

当客户端发起远程请求时,由于当前线程会被挂起直至服务端进程返回数据,所以一个远程方法是很耗时的,那么不能在UI线程中发起此远程请求;

由于服务端的Binder方法运行在Binder的线程池中,所以Binder方法不管是否耗时都应该采用同步的方式去实现,因为它已经运行在一个线程中了。

六、具体实例

进程间通信Demo实例

Android进程间通信IPC的更多相关文章

  1. 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6621566 上一篇文章Android进程间通信 ...

  2. 【Android】进程间通信IPC——Binder

    Binder是Android中的跨进程通信方式,bindService的时候,服务端返回Binder对象,通过该对象客户端可以从服务端获取数据.在进程间通信IPC——AIDL中创建了ICustomAi ...

  3. 【Android】进程间通信IPC——AIDL

    AIDL官网定义AIDL(Android 接口定义语言)与您可能使用过的其他 IDL 类似. 您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口. 在 Androi ...

  4. [置顶] 深入理解android之IPC机制与Binder框架

    [android之IPC机制与Binder框架] [Binder框架.Parcel.Proxy-Stub以及AIDL] Abstract [每个平台都会有自己一套跨进程的IPC机制,让不同进程里的两个 ...

  5. Android之IPC(aidl)

    IPC(Inter-Process Conmunication) 进程间通讯 在同一进程中,各个组件进行通信是十分方便的,普通的函数调用就可以解决:但是,对于处于不同进程中的组件来说,要进行通信,就需 ...

  6. Android 进程间通信

    什么鬼!单例居然失效了,一个地方设置值,另个地方居然取不到,这怎么可能?没道理啊!排查半天,发现这两就不在一个进程里,才恍然大悟-- 什么是进程 按照操作系统中的描述:进程一般指一个执行单元,在 PC ...

  7. Android DevArt6:Android中IPC的六种方式

    Android中IPC的六种方式 1.使用Bundle 最简单的进程间通信方式:Intent + Bundle: 支持三大组件:Activity.Service.BroadcastReceiver : ...

  8. [转]Android进程间通信

    Android进程间通信 一.Linux系统进程间通信有哪些方式? 1.socket: 2.name pipe命名管道: 3.message queue消息队列: 4.singal信号量: 5.sha ...

  9. Android 进程间通信——AIDL

    代码地址如下:http://www.demodashi.com/demo/12321.html 原文地址:http://blog.csdn.net/vnanyesheshou/article/deta ...

随机推荐

  1. Python爬虫之12306-分析请求总概述

    python爬虫也学了一段时间了.也爬过不少网站,最后我想用12306抢票器这个项目做一个对之前的学习的效果成见也是一个目标(开始学爬虫的时候,看到说,会爬12306,就会爬80%的网站),本人纯自学 ...

  2. return *this和return this有什么区别?

    return *this返回的是当前对象的克隆或者本身(若返回类型为A, 则是克隆, 若返回类型为A&, 则是本身 ). return this返回当前对象的地址(指向当前对象的指针). 转: ...

  3. 关于this绑定的四种方式

    一.前言 我们每天都在书写着有关于this的javascript代码,似懂非懂地在用着.前阵子在看了<你不知道的JavaScript上卷>之后,也算是被扫盲了一边关于this绑定的四种方式 ...

  4. Linux initramfs说明

    1.前言 最近在尝试对手头的开发板进行移植,此处记录initramfs挂载的基本流程,记录一下,以备后查.分析时是基于linux3.4.2 2. rootfs的挂载 start_kernel-> ...

  5. 2019年Python、Golang、Java、C++如何选择?

    前言 作为开发者我们都知道,开发后台语言可选择的方向会很多,比如,Java,go,Python,C/C++,PHP,NodeJs….等很多,这么多语言都有什么样的优势?如果让你学习一门后端语言,又该如 ...

  6. 【spark】dataframe常见操作

    spark dataframe派生于RDD类,但是提供了非常强大的数据操作功能.当然主要对类SQL的支持. 在实际工作中会遇到这样的情况,主要是会进行两个数据集的筛选.合并,重新入库. 首先加载数据集 ...

  7. 如何在html显示当前时间

    下边那个是一直快速跳转的 <!doctype html>  <html>  <head>  <meta charset="utf-8"&g ...

  8. appium 与 selenium python解决python 'WebElement' object does not support indexing 报错问题问题

    再用selenium编写测试脚本时,发现出现python 'WebElement' object does not support indexing 报错问题问题,再找一些解决方法时,发现Appium ...

  9. 2018-2019-2 20165328《网络对抗技术》Exp0 Kali安装week1

    1.下载Kaili安装资源并解压安装到虚拟机: 2.修改默认字体与共享文件设置: 3.更新软件源与下载中文输入法: 4.安装完成.

  10. 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)

    需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...