Android进程间通讯IPC

 

1、IPC的说明android

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

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

对于Android来讲,它是一种基于Linux内核的移动操做系统,但它的进程间通讯方式并不能彻底继承自Linux;相反,它有本身的进程间通讯方式。数据库

在Android中能够经过Binder轻松的实现进程间通讯。Android还支持Socket,经过Socket能够实现任意两个终端之间的通讯,同一设备的两个进程经过Socket通讯天然也是能够的。编程

 

2、Android中IPC的使用缓存

首先,只有面对多进程的状况才须要考虑进程间通讯。多进程的状况分为两种:服务器

第一种是一个应用由于某些缘由,自身须要采用多进程模式来实现,好比有些模块须要运行在单独的进程中、或者为了加大一个应用的可以使用内存,须要经过多进程来获取多份内存空间。网络

另外一种是当前应用须要向其余的应用获取数据,因此必须采用跨进程的方式来获取数据,好比使用系统的ContentProvider去查询数据。并发

经过给四大组件在AndroidMenifest中指定android:process属性,能够轻易地开启多进程模式。框架

 

3、Android中IPC带来的问题

两个应用共享数据:Android系统会为每一个应用分配一个惟一的UID,具备相同UID的应用才能共享数据。两个应用经过ShareUID跑在同一个进程是有要求的,须要这两个应用有相同的ShareUID而且签名相同才能够。在这种状况下,他们能够相互访问对方的私有数据,好比data目录,组件信息等,无论他们是否跑在同一个进程。

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

通常来讲,使用多进程会形成以下的问题:

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

(2)线程同步机制彻底失效(不在同一块内存,无论是所对象仍是锁全局类都没法保证线程同步)

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

(4)Application会屡次建立(由于建立新进程会分配独立虚拟机,至关于启动一个新的应用)

虽然说不能直接的共享内存,可是经过跨进程通讯仍是能够实现数据交互。

 

4、Android中各类IPC方式

一、使用Bundle

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

因为Bundle实现了Parcelable接口,因此它能够很方便的在不一样的进程间传输数据。固然咱们传输的数据必须可以被序列化,好比基本类型、实现了Parcelable接口的对象、实现了Serializable接口的对象以及一些Android支持的特殊对象。

二、使用文件共享

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

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

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

三、使用Messenger

Messenger能够理解为信使,经过它能够再不一样进程中传递Message对象,在Message中放入咱们须要传递的数据,就能够实现数据的进程间传递了。

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

四、使用AIDL

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

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

五、使用ContentProvider

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

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

六、使用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能够充分利用非共享内存的多处理器环境,能够简便地将你的应用分布在多台工做站上,应用程序就像运行在一个多处理器的计算机上同样。

 

 5、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的理解:

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

二、从Android Framework角度来讲,Binder是ServiceManager链接各类Manager和相应ManagerService的桥梁;

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

 

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

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

Binder的工做机制:

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

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

 

6、具体实例

进程间通讯Demo实例

相关文章
相关标签/搜索