原文来自:https://juejin.im/post/5aa08cb3f265da23766ad734 本人仅供学习笔记,如有侵权,请告知,我会删除!
一、Android 中的多进程
1、定义:
首先,进程一般指一个执行单元,在移动设备上就是一个程序或应用,我们在Android中所说的多进程(IPC)一般指一个应用包含多个进程。之所以要使用多进程有两方面原因:某些模块由于特殊的需求要运行在单独的进程;增加应用可用的内存空间。
2、开启多进程
Android中开启多线程只有一种方法,就是在AndroidManifest.xml中注册Service、Activity、Receiver、ContentProvider时指定android:process
属性,例如:
<service
android:name=".MyService"
android:process=":remote">
</service>
<activity
android:name=".MyActivity"
android:process="com.shh.ipctest.remote2">
</activity>
我们为MyService
和MyActivity
指定的android:process
属性值有所不同,它们的区别如下:
:remote
:以:
开头是一种简写,系统会在当前进程名前附件当前包名,完整的进程名为:com.shh.ipctest:remote
,同时以:
开头的进程属于当前应用的私有进程,其它应用的组件不能和它跑在同一进程。com.shh.ipctest.remote2
:这是完整的命名方式,不会附加包名,其它应用如果和该进程的ShareUID
、签名
相同,则可以和它跑在同一个进程,实现数据共享。
3、多进程引发的问题
开启多进程虽简单,但会引发如下问题,必须引起注意。
- 静态成员和单例模式失效
- 线程同步机制失效
- SharedPreferences 可靠性降低
- Application 被多次创建
对于前两个问题,可以这么理解,在Android中,系统会为每个应用或进程分配独立的虚拟机,不同的虚拟机自然占有不同的内存地址空间,所以同一个类的对象会产生不同的副本,导致共享数据失败,必然也不能实现线程的同步。
由于SharedPreferences
底层采用读写XML的文件的方式实现,多进程并发的的读写很可能导致数据异常。
Application
被多次创建和前两个问题类似,系统在分配多个虚拟机时相当于把同一个应用重新启动多次,必然会导致 Application 多次被创建,为了防止在 Application中出现无用的重复初始化,可使用进程名来做过滤,只让指定进程的才进行全局初始:
public class MyApplication extends Application{
@Override
public void onCreate() {
super.onCreate();
String processName = "com.shh.ipctest";
if (getPackageName().equals(processName)){
// do some init
}
}
4、Android中的多进程通信方式
Android中支持的多进程通信方式主要有以下几种,它们之间各有优缺点,可根据使用场景选择选择:
- AIDL:功能强大,支持进程间一对多的实时并发通信,并可实现 RPC (远程过程调用)。
- Messenger:支持一对多的串行实时通信, AIDL 的简化版本。
- Bundle:四大组件的进程通信方式,只能传输 Bundle 支持的数据类型。
- ContentProvider:强大的数据源访问支持,主要支持 CRUD 操作,一对多的进程间数据共享,例如我们的应用访问系统的通讯录数据。
- BroadcastReceiver:即广播,但只能单向通信,接收者只能被动的接收消息。
- 文件共享:在非高并发情况下共享简单的数据。
- Socket:通过网络传输数据。
这里我们主要讨论四大组件中Service在多进程通信中的使用,这就涉及到了 AIDL、Messenger这两种多进程通信方式,接下来重点看这两种 IPC 方式。
二、AIDL
AIDL 的意思是 Android 接口定义语言,使用AIDL进行进程间通信需要定义 服务端 和 客户端 ,其中客户端和服务端可以在同一应用也可以在不同应用。这里我们服务端可以看做是图书馆,为客户端提供近期新书查询、图书捐赠、新书通知的服务。三、Binder
在 AIDL 的例子中,客户端之所以能和服务端通信,主要依靠系统提供的Binder
类实现,它实现了IBinder
接口,我们在前边的例子已经用到了Binder
类,例如在服务端的 Service 中创建了一个Binder
对象并在onBind()
中返回:
四、Messenger
Messenger
是一种轻量级的多进程通信方式,它是在 AIDL 的基础上封装而成的,可以看做是 AIDL 的简化版,支持一对多的串行实时通信,一次只处理一个请求,不存在并发的问题。和 AIDL 的使用类似,但要简单的多,同样需要实现服务端和客户端。