IPC是Inter-Process Communication简写,意为进程间通信/跨进程通信,指代不同进程里面进行数据交换。因为该主题非常庞杂,所以分成多篇文章进行阐述,文章要点结构如下:
1.进程与线程
2.IPC的需求场景与常见系统的IPC机制
3.Android多进程模式部分简述
4.序列化与反序列化—Serializable与Parcelable接口
5.Binder与AIDL简介
6.IPC方式及其对比
当然通过这些并不能完全介绍完IPC机制,但是作为抛砖引玉的入门知识应该还是可以的,详细的可以自行搜索,或者阅读参考书籍与参考博客,如有错误,敬请指出。
1.进程与线程
进程是一般是指系统中的一个执行单元,在pc或者移动设备上通常情况下可指代一个应用;线程则是CPU里最小的执行单元,它是一种有限的系统资源。通常情况下,一个进程能拥有多个线程,二者存在包含关系。
在这里补充一下,Android中开辟新线程一般只有在AndroidManifest文件中给四大组件进行android:process进行指定,可以视为常规下的唯一手段。android:process的值也具有一些默认规定,当其值以“:”开头,则视为应用私有线程,其他应用的组件不能和它泡在同一个线程里面,而不以“:”开头则视为全局线程,其他应用可以通过ShareUID方式与他跑在同一个线程里面(UID是进程的标识,当不同应用具有相同ShareUID与签名时候,应用才能相互访问对方私有数据)。当然,也可以通过JNI在native进行fork一个新线程,但是这种方法属于特殊情况,非常用方式。
2.IPC的需求场景与常见系统的IPC机制
当操作系统中某些任务需要单独的进程进行,某些应用因为过大而且系统对应用存在内存限制,不同应用中需要进行跨进程的通信,这时候就需要IPC进行解决(系统提供的ContentProvider去查询数据)。
当然不止Android需要采取IPC机制,所有操作系统都需要对应的IPC机制,如Linux上可以运用命名管道,共享内容,信号量等,Window吸用可以通过剪切板,管道和邮槽等。Android虽然基于Linux系统,但是他的IPC机制并不完全继承于Linux,而且拥有自己读的进程间通信方式。Android自己特有的IPC方式就是Binder了,当然还有其他的方式如Socket进行不同端的通信(也可以用于同端不同进程通信)。
3.Android多进程模式部分简述
应用的多进程开始方式在上头我们简单说明过了,但是我们一般很少采用开辟新进程,不仅因为其对应的开销比较大,还具有许多需要克服的困难和问题。一般来说,多进程会遇到下面几种问题:
(1)所有静态数据与单例模式全部失效;
(2)SharePreference的可靠性下降;(SP的底层机制是通过读写XML文件实现,多进程容易导致并发读写出现问题)
(3)线程的同步机制失效;(本质上与1是一致的,因为1的问题,所以无论是锁对象还是锁全局类都无法保证线程同步,造成该问题)
(4)Application会被多次创建;
4.序列化与反序列化—Serializable与Parcelable接口
序列化是将数据对象的状态信息转化成可存储或者传输的形式,多是字节或者xml格式。对象序列化机制是java内建的一种对象持久化机制,通过它可以将对象状态转化成字节数组,需要的时候再通过反序列化将字节数组转化成对象。对象的序列化可以很容易地在jvm里的活动对象与字节数组(流)的相互转化。
其中Serializable与Parcelable接口均是为了库本身锁提供的序列化接口:
(1)Serializable
数据对象类只需要对接该接口,则完成序列化。其序列化与反序列化都由内部自行实现。我们可以自行选择是否要在对象类中指定serialVersionUID,指定与否都可以完成序列化,但是当数据原型类发生结构改变时,会有不可忽略的影响。
serialVersionUID是用于辅助序列化与反序列化过程的 ,原则上唯有序列化后数据里的serialVersionUID与对应类的serialVersionUID一致才能进行反序列化过程,否则将会发生反序列化失败,程序会出现crash。当我们没有指定serialVersionUID时候,系统在序列化时会根据类的结构计算当前类的hash值并赋予serialVersionUID,这时候如果我们结构发生改变(一般修改如增加、删除成员变量),就会造成对应的前后hash值不一致,反序列化 将会失败,通常会造成程序挂掉。尤其是发生重大结构改变(类名修改,成员变量),此情况下反序列化必定造成程序崩溃。所以当指定serialVersionUID后就能避免这种情况,当然发生改变的地方相对应的默认处理(如增加了某个变量,反序列化后该变量值为空)。
(1)Parcelable
数据对象对接该接口,就需要实现两个:writeToParcel与CREATOR。Pracel内部包装了可序列化的数据,可供Binder进行传输。由此可知writeToParcel是用于序列化过程,CREATOR则用于反序列化过程。系统也提供了许多实现了Parcelable接口的类,如Intent,Bundle,Bitmap等,List和Map也可以序列化,但是其里面的每个元素都是可序列化的。
综上,二者都是可以实现序列化的,当然要某个数据模型类实现可序列化,其成员也都需要是可序列化元素。其中Serializable为Java中的序列化接口,Parcelable则属于Android提出的。他们之间的取舍也有一定差异:
Serializable使用简单但是开销很大,需要大量I/O操作;
Pracelable则更适用于Android平台,效率很高,但是使用麻烦。
5.Binder与AIDL简介
Binder是Android里的一种进程间通信(IPC)的机制,并非单纯的一个东西,可以理解成是一套东西。以IPC角度看,它是一种“设备”,用于实现数据传递机制。以Android应用层来看,是客户端与服务端的一种媒介,用于连接各种Manager(如ActivityManageer、WindowManager等)与ServiceManager,类似于桥梁的作用,其与TCP/IP中一个典型的服务连接过程十分相似。Binder大体上可以由下列组成
Binder驱动→路由器:
Service Manager→DNS
Binder Client→客户端
Binder Server→服务器
(详细可见参考博客)
客户端线程1发送请求,启用bindservice时候,通过ServiceManager查找到服务端线程2,之后服务端会返回一个包含Binder对象,从servicemanager获取客户端位置,通过binderservice将数据,服务传递给客户端。
当然Binder里所传递的服务一般分成普通服务和AIDL服务。当然Binder并不是非要用于进程间通信,一般不涉及进程间通信,如Binder常用于Service中,普通的Service并不单独于新的进程,但这种不涉及Binder的核心。接下来我们解释一下AIDL:
AIDL是Android Interface Definition Language(Android接口定义语言)的缩写,用于定义服务端与客户端的通信一种描述性语言,更具体地来说是Android用于进程间通信的一种模板。当然AIDL支持的类型有:
(1)八种基本数据类型:byte、char、short、int、long、float、double、boolean
(2)String,CharSequence
(3)实现了Parcelable接口的数据类型
(4)List 类型。List承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
(5)Map类型。Map承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
补充一下,AIDL文件以 .aidl 为后缀名,但是起作用的并不是AIDL文件,而是系统通过aidl文件所生成的java文件。
6.IPC方式及其对比
(1)Bundle:
优点:简单易用
缺点:只能传输Bundle支持的数据类型
适用场景:四大组件之间的进程通信
(1)文件共享:
优点:简单易用
缺点:不适合高并发场景,无法做到进程间的即时通信
适用场景:无并发的访问情景,交换的数据为实时性不高的场景
(1)AIDL:
优点:功能强大,支持一对多并发通信,支持实时通信
缺点:使用比较复杂,需要处理好线程同步问题
适用场景:一对多通信,且有RPC需求
(1)Messenger:
优点:功能一般,支持一对多串行通信,支持实时通信
缺点:不能很好地处理高并发场景,不支持RPC,数据通过Message进行传输,因此只能传输bundle支持的数据类型
适用场景:低并发的一对多即时通信,无RPC需求,或者无需返回结果的RPC需求
(1)ContentProvider:
优点:数据源访问方面功能强大,支持一对多并发数据共享,可通过Call方法扩展其他操作
缺点:可视为受约束的AIDL,主要提供数据源的CRUD(Create、Read、Update、Delete)操作
适用场景:一对多的进程间的数据共享
(1)Socket:
优点:功能强大,可进行网络传输字节流,支持一对多并发即时通信
缺点:实现繁琐,不支持直接的RPC
适用场景:网络数据交换
目前理解的仍很粗浅,如有错误敬请指正,详细的可见参考书籍和参考博客。
---------------------
参考书籍:《Android开发艺术探索》
参考博文:
作者:ClAndEllen 来源:CSDN 题目:Android面试系列文章2018之Android部分Binder机制篇
链接:https://blog.csdn.net/ClAndEllen/article/details/79343389
---------------------