Android进程间通信IPC
一、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方法不管是否耗时都应该采用同步的方式去实现,因为它已经运行在一个线程中了。
六、具体实例
Android进程间通信IPC的更多相关文章
- 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6621566 上一篇文章Android进程间通信 ...
- 【Android】进程间通信IPC——Binder
Binder是Android中的跨进程通信方式,bindService的时候,服务端返回Binder对象,通过该对象客户端可以从服务端获取数据.在进程间通信IPC——AIDL中创建了ICustomAi ...
- 【Android】进程间通信IPC——AIDL
AIDL官网定义AIDL(Android 接口定义语言)与您可能使用过的其他 IDL 类似. 您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口. 在 Androi ...
- [置顶] 深入理解android之IPC机制与Binder框架
[android之IPC机制与Binder框架] [Binder框架.Parcel.Proxy-Stub以及AIDL] Abstract [每个平台都会有自己一套跨进程的IPC机制,让不同进程里的两个 ...
- Android之IPC(aidl)
IPC(Inter-Process Conmunication) 进程间通讯 在同一进程中,各个组件进行通信是十分方便的,普通的函数调用就可以解决:但是,对于处于不同进程中的组件来说,要进行通信,就需 ...
- Android 进程间通信
什么鬼!单例居然失效了,一个地方设置值,另个地方居然取不到,这怎么可能?没道理啊!排查半天,发现这两就不在一个进程里,才恍然大悟-- 什么是进程 按照操作系统中的描述:进程一般指一个执行单元,在 PC ...
- Android DevArt6:Android中IPC的六种方式
Android中IPC的六种方式 1.使用Bundle 最简单的进程间通信方式:Intent + Bundle: 支持三大组件:Activity.Service.BroadcastReceiver : ...
- [转]Android进程间通信
Android进程间通信 一.Linux系统进程间通信有哪些方式? 1.socket: 2.name pipe命名管道: 3.message queue消息队列: 4.singal信号量: 5.sha ...
- Android 进程间通信——AIDL
代码地址如下:http://www.demodashi.com/demo/12321.html 原文地址:http://blog.csdn.net/vnanyesheshou/article/deta ...
随机推荐
- sonar服务搭建
1.下载安装包,我安装的是6.7.6版本 https://www.sonarqube.org/downloads/ 2.安装前的环境要求 JDK1.8+ 数据库,我用的是Mysql5.6版本 3. ...
- 【干货】使用SIFT取证工作站校验文件哈希----哈希一致则文件具备完整性
此实验来源于课程活动部分:第1单元:计算机取证基础 1.3活动和讨论 活动:* nix系统中文件的基本散列 注意:本博客更多的信息可能没有交代完善,有的人看不明白是因为,我知道,但是没有写出来.本 ...
- 试题 E: 迷宫
[问题描述]下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可以通行的地方.010000000100001001110000迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个 ...
- Codeforces 558E A Simple Task (计数排序&&线段树优化)
题目链接:http://codeforces.com/contest/558/problem/E E. A Simple Task time limit per test5 seconds memor ...
- 初学python之路-day08
#学习了编码后,还要了解三种字符串.# 一.# 普通字符串:u''以字符作为输出单位,# print(u'abc') # 用于显示abc# # 二进制字符串:b'' 二进制字符串以字节作为输出单位# ...
- 用 pdf.js兼容部分安卓显示PDF在线预览 时,a标签直接链接参数文件不能含中文的解决办法
例子: 项目部署在 Tomcat 上的: <a href="../generic/web/viewer.html?file=doc/register/要显示的文件.pdf" ...
- Runtime个别API的使用
Runtime 关于属性部分API的说明以及使用方法 使用Runtime机制需要引入头文件: #import <objc/runtime.h> 1: Ivar *class_copyIv ...
- [原创]Cadence Allegro16.6安装
选择Cancel. lisence managner安装完成,然后安装Product installation Cadence OrCad Allegro SPB 16.6 完整版+和谐文件 链接:h ...
- Mybatis 源码学习系列
前言 很久以前,我们学习了Java,从一个控制台的 Hello world .开始,我们进入了面向对象的世界. 然后由学习了SQL语言,可以写出SQL语句来将尘封在硬盘之下的数据库数据,展现出来. 后 ...
- Snakes 的 Naïve Graph
题解: 首先分析一下这个问题 发现等价于是求n之内与n互素的数的个数,即欧拉函数 这个可以线性筛 但发现还应该减去$x^2==1$的情况 这个东西不是那么好处理 考虑用中国剩余定理拆 因为$p1^{a ...