1.Android IPC机制
IPC是Inter-process Communication的缩写,含义为进程通信或者跨进程通信,是指两个进程之间进行数据交换的过程。进程和线程是不同的概念,按照操作系统中的描述,线程是CPU调度的最小单元,同时线程是一种有限的系统资源。而进程一般是指一个执行单元,在PC和移动设备上指的是一个程序或者是一个应用。一个进程可以包含多个线程,因此进程和线程是包含与被包含的关系。任何一个操作系统都有相应的IPC机制。例如:
Linux上可以通过命名管道、共享内容、信号量等来进行进程通信。
Windows上可以通过剪贴板、管道和邮槽等来进行进程通信。
Android系统可以通过Binder、Socket进行通信。
2.Android中的多进程模式
2.1 开启多进程模式
在Android中使用多进程只有一种方法,那就是给四大组件(Activity、Service、Receiver、ContentProvider)在AndroidMenifest中指定android:process属性,除此之外没有其他方法,也就是说我们无法给一个线程或者一个实体类指定其运行所在的进程。 image.png上面的示例中分别位SecondActivity和ThirdActivity指定了process属性值不同,说明当前应用又增加了两个进程,其中MainActivity没有指定process属性,那么它运行在默认进程中,默认进程的进程名是包名。上面的示例中的android:process属性分别为“:remote”和“com.ryg.chapter_2.remote”,这两种方式是又区别的,第一种的":"的含义是指在当前附加上当前的包名,进程与":"开头的进程属于当前应用私有进程,其他应用的组件不可以和它跑在同一个进程中,而进程名不以":"开头的进程属于全局进程,其他应用通过ShareUID方式可以和它在同一个进程中。第二种方式是完整的命名方式,不附加包名信息。
2.2多进程模式的运行机制。
Android为每一个应用分配了一个独立的虚拟机,或者说为每个进程都分配一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这就导致在不同虚拟机中访问同一个类的对象会产生多个副本。所有运行在不同进程中的四大组件,只要他们之间需要通过内存来共享数据,都会共享失败,这就是多个进程所带来的主要影响。
Q:一般使用多进程会造成什么问题?
- 静态成员和单例模式完全失效。
- 线程同步机制完全失效,因为不在同一块内存,不同进程锁的不是同一个对象。
- SharedPreferences的可靠性下降。因为SharedPreferences不支持两个进程同时去执行写操作,否者会导致一定机率的数据丢失,这是因为SharedPreferences底层是通过读/写XML文件来实现的,并发写显然是有可能出现问题的。
- Application会多次创建。
3.IPC基础概念介绍
3.1 Serializable接口
Serializable是Java所提供的一个系列化接口,它是一个空接口,为对象提供标砖的序列化和反序列化。使用Serializable来实现序列化相当简单,只需要在类的生命中指定指定一个类似下面的标识即可自动实现默认的序列化过程。
image.png
private static final long serialVersionUID=8711368828010083044L
可以通过实现Serializable的接口也可以实现序列化和反序列化,实现起来非常简单,几乎所有的工作都被系统自动完成。如何让进行对象的序列化和反序列化也非常简单,只需要ObjectOutputStream和ObjectInputStream即可轻松实现。
serialVersionUID是用来辅助序列化和反序列化过程的,原则上序列化的数据中的serialVersionUID只有和当前类的serialVersionUID相同才能够正常地被反序列化。serialVersionUID的工作原理:serialVersionUID的工作原理:序列化的时候系统会把当前类的serialVersionUID写入序列化文件中,当反序列化的时候系统会去检测文件中的serialVersionUID,看它是否和当前的serivalVersionUID一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化。否则就说明当前类和序列化的类相比发生了某些变换,比如成员变量的数量、类型可能发生了改变,这个时候无法正常反序列化的。
如果不手动指定serialVersionUID的值,反序列化时当前类有所改变,比如增加或者删除了某些成员变量,那么系统就会重新计算当前类的hash值并把它赋值给serialVersionUID,这个是皇后当前的serialVersionUID就和序列化数据的serialVersionUID不一致,反序列失败。
3.2 Parcelable接口
Parcelable也是一个接口,只要实现这个接口,一个类的对象就可以实现序列化并可以通过Intent和Binder传递。序列化功能由writeToParcel方法来完成最终时通过Parcel中的一系列write方法来完成的。反序列化的功能由CREATOR来完成,其内部标明了如何让创建序列化对象和数组,并通过Parcel的一系列read方法来完成反序列化过程。内容描述功能由describeContents方法来完成,几乎在所有情况下这个方法都应该返回0,仅当当前对象存在文件描述时,此方法返回1.
Q:Parcelable和Serializable的区别:
Parcelable和Serializable都能实现序列化并且都可用于Intent间的数据传递。Serializable是Java中序列化接口,其使用起来简单但是开销很大,序列化和反序列化过程程需要大量的I/O操作。而Parcelable是Android的序列化方式,因此更适合在Android平台上,它的缺点就是使用起来稍微麻烦点,但是它的效率很高,因此是Android举荐的序列化方式。Parcelable主要是在内存序列化上,如果将对象序列化到存储设备中或者对象序列化后通过网络传输,Parcelable使用起来比较复杂,所以举荐选用Serializable。
3.3 Binder
参考链接https://blog.csdn.net/zxc637841323/article/details/79825183
4.Android中的IPC方式
4.1使用Bundle
四大组件中的三大组件(Activity,Service,Receiver)都是支持在Intent中传递Bundle数据,Bundle实现了Parceable接口,所以它可以方便地在不同的进程间传输。
4.2使用文件共享
共享文件是一种不错的进程间通信方式,两个进程通过读/写同一个文件来交换数据。通过文件共享这种方式来共享数据对文件格式是没有具体要求的,只要读/写双方约定数据格式即可。但是存在并发的问题,因此文件共享方式适合在对数据同步要求不高的进程之间进行通信,并妥善处理并发读/写问题。
4.3使用Messenger
Messagnger的底层四实现AIDL,它可以子在不同进程中传递Message对象,在Message中放入我们需要传递的数据,就可以实现数据在进程上传递。它一次处理一个请求,服务端中不存在并发执行的情形。 Messenger工作原理
4.4使用AIDL
使用Messenger进行进程间的通信的方法,Messenger是以串行的方式处理客户端发送来的小时,如果有大量的消息同时发送到服务端,服务端只能一个个处理,如果有大量的并发请求,而且Messanger的主要作用是为了传递消息,如果需要跨进程调用服务端的方法,那么用Messanger就不太合适。而AIDL可以实现跨进程的方法调用。AIDL文件支持的数据类型: image.png
4.5使用ContentProvider
ContentProvider是Android中提供的专门用于不同应用间进行数据共享的方式,ContrntProvider的底层也是Binder,系统设置了许多ContentProvider,比如通讯录信息、日程表信息等,要跨进程访问这些信息,只需要通过COntentResolver的query、update、insert和delete方法即可。
4.6使用Socket
Socket也称为“套接字”,是网络通信中的概念,它分为流式套接字和用户套接字两种,分别对应于网络的传输控制层中的TCP和UDP协议。TCP协议是面向连接的歇息,提供稳定的双向通信功能,TCP连接的建立需要经过“三次握手”才能完成,为了提供稳定的数据传输功能,其本身提供了超时重传机制,因此具有很高的稳定性。而UDP是无连接的,提供不稳定的单向通信功能,当然UDP也可以实现双向通信功能,在性能上,UDP具有更好的效率,其缺点不是保证数据一定能够正确传输,尤其是在网络拥堵的情况下。
5.Binder连接池
Binder连接的主要作用就是将每个业务模块的Binder请求统一转发到远程Service中去执行,避免了重复创建Service的过程,很适合实现数量较多的应用之间的线程通信。 image.png
如果有新的业务模块需要添加新的AIDL,那么在它实现自己的AIDL接口后,只需要修改BinderPoolImpl中的queryBinder方法,给自己添加一个新的binderCode并返回对应的Binder对象即可,不需要做其他修改,也不需要创建新的Service。
6 选择合适的IPC方式
image.png以上内容来源于《Android开发艺术与探索》
网友评论