一 前言
IPC(Inter Process Commotion),即进程间通信。
1. 对比
Windows:通过剪贴板、管道、邮槽进行通信
Linux:命名管道、共享内容、信号量等来进行通信
Android:Android的内核是Linux,但是它的进程通信方式并不是完全继承自Linux的,Android有自己的进程通信方式,比如Binder、Socket
2. 什么时候会用到多进程呢?
- 一个应用需要多个进程实现
- 加大一个应用的可用内存
- 当前应用需要向其它应用获取数据
二 多进程
1.多进程两种使用方式
- AndroidManifest中android:process
- JNI的native层fork一个新的进程
2 使用多进程会带来的问题
- 静态成元和单例模式完全失效
- 线程同步机制完全失效
- SharedPreferences会出问题
- Application创建多次
三 跨进程通信方式
Android中的跨进程通信方式有以下几种:
Bundle、文件共享、使用Messenger、使用AIDL、使用ContentProvider、Socket
Bundle
四大组件中的Activity、Service、Receiver传递数据可以用Bundle进行,
由于Bundle实现了Parcelable接口,所以它可以很方便在不通进程中传递数据。
那么Bundler支持的数据类型有哪些呢?
- 基本数据类型
- 实现了Parcelable接口的对象
- 实现了Serializable接口的对象
- Bundler支持的一些特殊类型的对象
注意:Bundler不支持的类型不能传输
有什么方法可以解决这个问题呢?
有一个需求两个进程进程1运算,传递给进程2,数据不能Bundler传递?
第一步:进程1起动一个Service,在Service里进行计算。
第二步:计算完再启动进程2
由于Service也运行在进程2中,进程2就可以拿到进程1中的数据了。
文件共享
Windows文件操作:
一个文件加了排斥锁,其他文件就不能对它进行操作了。
Android文件操作:
Android中的文件操作继承自Linux,文件可以并发读写。
Android文件共享的步骤:
第一步:
在进程1中的Activity序列化一个对象到手机存储的一个文件里
第二步:
在进程2中的Activity反序列化,即可得到对象
注意1:对数据格式没有要求,但是不适合并发读写,并发读写会造成数据不是最新的,适合同步要求不高的进程通信。
注意2: SharedPreference
SharedPreference是Android一种轻量级存储,但是SharedPreference系统对它的读写采用了缓存策略,所以对它的并发读写会非常不可靠
使用Messenger
底层用的AIDL,一次只处理一个请求,在服务端不用考虑线程同步的问题(服务端存在并发)。
1.服务端
第一步 客户端创建一个Service来处理客户端的连接请求
第二步 创建一个Handler并通过它来创建一个Message对象
第三步 在Service的onBind里返回这个Message的底层对象
2.客户端
分成两种:
-
客户端无回应
绑定服务端的Service,绑定成功,用服务端返回的IBinder对象创建一个Messenger,通过它可以向服务端发送消息。 -
客户端有回应
还需要创建一个Handler并创建一个新的Messenger,把这个Messenger通过Message的realyTo参数传递给服务端,服务端通过realyTo参数回应。
使用AIDL
如果我们有大量的请求发送到服务端,Messenger就不合适了,因为Messenger只能一个个接收。如果需要访问服务端的方法,Messenger也无法做到,这个时候我们就要用到AIDL了我们知道Messenger底层实现是AIDL,只是系统对它做了封装。
客户端
第一步 创建一个Service监听客户端的请求
第二步 创建一个AIDL文件中的声明
第三步 Service实现这个AIDL接口
服务端
第一步 绑定服务端Service,绑定成功,服务端返回的Binder对象转成AIDL接口所属的类型,
第二步 调用AIDL方法
使用ContentProvider
四大组件之一,用于不同应用间数据共享。底层用的是Binder。
可以访问系统消息
访问方式:
ContentResolver的query、update、insert、delete方法即可
使用Socket
称为套接字,用于网络通信
分为流式套接字,用户数据报套接字
流式套接字对应TCP层
数据报套接字对应UDP层
网友评论