IPC机制总结

IPC机制总结,第1张

概述IPC机制进程间通信进程和线程线程是CPU调度的最小单元,同时线程是一种有限的系统资源。进程一般指一个执行单元,在PC和移动设备上指一个程序或者一个应用。一个进程可以包含多个线程。多进程情况一个应用出自某些原因采用多进程模式实现,比如希望通过多进程获取多份内存空 IPC机制

进程间通信

进程和线程线程是cpu调度的最小单元,同时线程是一种有限的系统资源。进程一般指一个执行单元,在PC和移动设备上指一个程序或者一个应用。一个进程可以包含多个线程。多进程情况一个应用出自某些原因采用多进程模式实现,比如希望通过多进程获取多份内存空间。当前应用需要向其他应用获取数据。某些模块有运行在单独进程中的需要。AndroID中的进程间通信方式Binder实现进程间通信Socket实现任意两个终端之间的通信或者一个设备上的两个进程间的通信。

AndroID中的多进程模式

开启多进程模式

给四大组件在AndroIDMenifest中指定androID:process属性。非常规:通过JNI在native层去fork一个新的进程。

多进程模式的运行机制

多进程绝非仅仅是指定一个androID:process属性那么简单。一般来说,使用多进程会造成以下一个方面的问题:

静态成员变量和单例模式完全失效。线程同步机制完全失效。SharedPreferences的可靠性下降。Application会多次创建。

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

为了解决这些问题,系统提供了很多跨进程通信方法。

IPC基础概念

Serializable和Serializable接口都可以完成对象序列化的过程,序列化是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

Serializable接口

Java提供的一个序列化接口,在类声明中指定一个private static final long serialVersionUID(序列化后的数据中的serialVersionUID只有和当前类的相同才能够正常的被反序列化),采用ObjectinputStream和ObjectOutputStream可以实现序列化。需要注意的是:序列化恢复的对象和原对象内容完全一样,但是两者并不是同一个对象。

serialVersionUID的工作机制:序列化时系统会把当前类的serialVersionUID写入序列化文件或者其它中介中,当反序列化的时候系统又回去检测文件中的serialVersionUID,看他是否和当前类的serialVersionUID一致,如果一致就说明序列化的类的版本和当前版本是相同的,这个时候可以成功反序列化。

另外,静态成员变量不属于类不属于对象,所以不会参与序列化过程;其次用transIEnt关键字标记的成员变量也不参与序列化过程。

Parcelable接口

实现这个接口,一个类的对象就可以通过Intent和Binder传递。 系统已经为我们提供了许多实现了Parcelable接口的类,可以直接序列化,比如Intent、Bundle、Bitmap等等,同时List和Map也可以序列化,前提是它们里面每个元素都是可以序列化的。

Parcelable和Serializable的比较:

Serializable的作用是为了保持对象的属性到本地文件、数据库、网络流以方便数据传输,当然这种传输可以是进程内或者不同进程之间的,Serializable开销很大,在序列化和反序列化当中需要进行大量的I/O *** 作,效率不高。主要用于数据持久化和网络传输。

相较而言,Parcelable是AndroID中的序列化方式,效率很高,内存开销较小,主要用在内存序列上, 是为了在不同组件间以及不同AndroID应用间(AIDL)高效传输数据而设计,Parcelable是通过IBinder通信的消息的载体 。将对象序列化到存储设备或者网络传输也是可以的,但是过程较Serializable稍微复杂,而且因为AndroID不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化。

Binder

直观来说,Binder是AndroID中的一个类,它实现了IBinder接口。从IPC的角度看,Binder是AndroID中一种跨进程通信方式,BInder还可以理解为一种虚拟的物理设备,他的设备驱动是/dev/binder,该通信方式在linux中没有;从AndroID Framework的角度说,Binder是ServiceManager连接各种Manager和响应ManagerService的桥梁;从AndroID应用层来说,Binder是客户端和服务端进行通信的媒介,当bindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个Binder对象,客户端可以获取服务端提供的服务或者数据,包括普通服务和基于AIDL的服务。

AndroID中的IPC方式

使用Bundle

四大组件中的三大组件Activity、Service、Receiver都是支持在Intent中传递Bundle数据的,由于Bundle实现了Parcelable接口,可以方便地在不同的进程之间传输。

使用文件共享

由于AndroID系统基于linux,使其并发读写文件可以没有限制的进行,但是也必须考虑可能出现的线程安全问题,比较适合对于数据同步要求不高的进程之间通信。

其中,对于SharedPreferences存储来说,系统对它的读写有一定的缓存策略,即在内存中会有一份SharedPreferences文件的缓存,所以再多进程模式下,系统对它的读写就变得不可靠,在并发读写时有很大几率丢失数据,因此不建议在进程间通信时使用。

使用Messenger(略过)

Messenger可以在不同进程中传递Message对象,轻松实现数据的进程间传递。使用方法很简单,对AIDL做了封装,可以很简便地进行进程间通信。

使用AIDL

服务端创建Service监听客户端的连接请求,然后创建AIDL文件,将暴露给客户端的接口在这个AIDL文件中声明,最后在Service中实现这个AIDL接口即可。客户端首先需要绑定服务端的Service,绑定成功后将服务端返回的Binder对象转换成为AIDL接口所属的类型,接着就可以调用AIDL中的方法了。AIDL接口的创建与远程服务端Service的实现和客户端的实现、

使用ContentProvIDer(待补充)

使用Socket

可以通过Socket来实现进程间的通信,Socket也称为“套接字”,分为流式套接字和用户数据报套接字两种,分别对应了网络传输控制层中的TCP和UDP协议。通过Socket不仅仅能够实现进程间的通信,还可以实现设备间的通信,前提是这些设备之间的IP地址互相可见。

Binder连接池

Binder连接池的主要作用就是将每个业务模块的Binder请求统一转发到远程Service中去执行,从而避免重复创建Service的过程,可以大大提高AIDL的开发效率。

选择合适的IPC方式

选择合适的IPC方式完成多进程的开发场景。

名称优点缺点适用场景
Bundle简单易用只能传输Bundle支持的数据类型四大组件间的进程间通信
文件共享简单易用不适合高并发场景,并且无法做到进程间的即时通信无并发访问情景,交换简单的数据实时性不高的场景
AIDL功能强大,支持一对多并发通信,支持实时通信使用稍复杂,需要处理好线程同步一对多通信而且有RPC(远程过程调用)需求
Messenger功能一般,支持一对多串行通信,支持实时通信不能很好地处理高并发情形,不能支持RPC,数据通过Message进行传输,因此只能传输Bundle支持的数据类型低并发的一对多即时通信,无RPC需求,或者无需要返回结果的RPC需求
ContentProvIDer在数据源访问方面功能强大,支持一对多并发数据共享,可以通过Call方法扩展其他 *** 作可以理解为受约束的AIDL,主要提供数据源的CRUD *** 作一对多的进程间数据共享
Socket功能强大,可以通过网络传输字节流,支持一对多并发实时通信实现细节稍微繁琐,不支持直接的RPC网络数据交换
总结

以上是内存溢出为你收集整理的IPC机制总结全部内容,希望文章能够帮你解决IPC机制总结所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1065856.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存