一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
进程间通讯简介
进程间通讯(InterProcess Communication 缩写IPC)顾名思义就是进程与进程之间的数据交互,IPC不是Android独有的特性,所有的操作系统都有对应的IPC机制。对于Android而言,一个应用便是一个进程,所有的数据交互都在一个进程内。只有在多进程情况下才需要考虑IPC机制。
在Android当中比较常用的两种情况需要考虑IPC,①:应用本身需要开启多个进程进行使用,比如Webview的使用等。②:获取其他应用的数据,比如通讯录、短信等。
为什么要使用多进程
因为在app运行时,虚拟机会给进程分配运行内存,但是分配使用的内存是有限制的,主要还是根据手机机型而定,像webview和加载bitmap这类操作都会增加内存的开销,提高OOM的风险。
开启多进程
在Android 系统中开启多进程的方式是在清单文件中给四大组件设置android:process属性。应用的主进程默认是以包名命名的进程,修改的话需要在application节点设置android:process属性即可。
process属性设置
- 以
:开头的命名的进程,在运行时会被加上默认的包名,并且指定其为当前应用的私有进程,其他的应用组件无法和它运行在同一进程。 - 以
com.example.a.process这样完整参数命名的进程,在运行时不会别加上默认的包名,当存在ShareUID、签名相同的其它应用,则可以和它跑在同一个进程,实现数据共享。
多进程引发的问题
- 静态成员和单例模式失效
- 线程同步机制失效
- SharedPreferences 可靠性降低
- Application 被多次创建
进程间通信方式
使用Bundle
Activity、Service、BroadcastReceiver通过Intent传递Bundle数据。由于Bundle在借助Intent传递的数据可以是boolean、byte、int、long、float、double、string等基本类型或它们对应的数组,也可以是对象或对象数组。当Bundle传递的是对象或对象数组时,都需要进行序列化,也就是实现Serializable或Parcelable接口。
该通讯方式适合A进程启动并传递数据到B进程中的Activity、Service、Receiver。
使用文件共享
通过读写同一个文件来交换数据,由通讯双方约定相应的数据格式,该数据需要满足序列化要求。
该通讯方式适合对数据没有并发要求的进程间通讯,一般并不推荐使用。
使用ContentProvider
ContentProvider是 Android 四大组件之一,为 App 存取数据提供统一的对外接口,让不同的应用之间可以共享数据。
该通讯方式适合两个典型的使用场景:一种是通过实现代码访问其他应用中的现有的ContentProvider用来获得数据;另一种是创建新的ContentProvider,与其他应用共享数据。
使用Messager
是一种轻量级的多进程通信方式,它是在 AIDL 的基础上封装而成的,可以看做是 AIDL 的简化版,支持一对多的串行实时通信,一次只处理一个请求,不存在并发的问题。和 AIDL 的使用类似,但要简单的多,同样需要实现服务端和客户端。
该通讯方式适合传递消息,因为Messager方法只能传递消息,不能跨进程调用方法。
使用AIDL
AIDL 的意思是 Android 接口定义语言,AIDL接口可以通过编写AIDL文件然后由系统生成对应的Binder类,通过Binder我们就可以进行跨进程通信了
需要了解一下AIDL文件中支持的几种类型:
- 基本类型:如
int、byte等 String和CharSequence- List:只支持
ArrayList,元素也是AIDL支持的类型 - Map:只支持
HashMap,key、value也是AIDL支持的类型 - 实现了
Parcelable接口的对象 - AIDL:所有的AIDL接口本身也可以在AIDL文件中使用
该通讯方式是android进程间通讯推荐的方式,可以在同一个应用,也可以在不同应用进行通讯。