要点提炼|Android开发艺术之IPC
要点摘要
一、IPC基础和概念
1、多进程模式
- IPC基础及概念
- 多进程模式
- 序列化
- Serializable接口
- Parcelable接口
- Binder机制
- IPC方式
- Bundle
- 文件共享
- AIDL
- Messager
- ContentProvider
- Socket
- Binder连接池
a.进程&线程
- 进程:一般指一个执行单元,在PC和移动设备上指一个程序或应用。
- 线程:CPU调度的最小单元。线程是一种有限的系统资源。
两者关系: 一个进程可包含多个线程,即一个应用程序上可以同时执行多个任务。
- 主线程(UI线程):UI操作
- 有限个子线程:耗时操作
注意:不可在主线程做大量耗时操作,会导致ANR(应用无响应)。
b.开启多线程
- (不常用)通过JNI在native层fork一个新的进程。
- (常用)在AndroidMenifest中给四大组件指定属性
android:process
,进程名的命名规则:- 默认进程:没有指定该属性则运行在默认进程,其进程名就是包名。
- 以“:”开头的进程:
- 省略包名,如
android:process=":remote"
,表示进程名为com.example.myapplication:remote
。 - 属于当前应用的私有进程,其他进程的组件不能和他跑在同一进程中。
- 省略包名,如
- 完整命名的进程:
- 如
android:process="com.example.myapplication.remote"
。 - 属于全局进程,其他应用可以通过ShareUID方式和他跑在用一个进程中。
- 如
UID&ShareUID:
Android系统为每个应用分配一个唯一的UID,具有相同UID的应用才能共享数据。
两个应用通过ShareUID跑在同一进程的条件:ShareUID相同且签名也相同。
- 满足上述条件的两个应用,无论是否跑在同一进程,它们可共享data目录,组件信息。
- 若跑在同一进程,它们除了可共享data目录、组件信息,还可共享内存数据。它们就像是一个应用的两个部分。
c.查看进程信息的方法
- 通过DDMS视图查看进程信息。
- 通过shell查看,命令为:
adb shell ps|grep 包名
。
d.需要进程间通信的必要性:
所有运行在不同进程的四大组件,只要它们之间需要通过内存在共享数据,都会共享失败。
原因:由于Android为每个应用分配了独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这会导致在不同的虚拟机中访问同一个类的对象会产生多份副本。
e.多进程造成的影响,总结为以下四方面:
①静态变量和单例模式失效。
由独立的虚拟机造成。
②线程同步机制失效。
原因同上。
③SharedPreference的不可靠下降。
SharedPreferences不支持两个进程同时进行读写操作,即不支持并发读写,有一定几率导致数据丢失。
④Application多次创建。
Android系统会为新的进程分配独立虚拟机,相当于系统又把这个应用重新启动了一次。
2.序列化
a.序列化的介绍
- 含义:序列化表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
- 场景:需要通过Intent和Binder等传输类对象就必须完成对象的序列化过程。
- 两种方式:实现Serializable/Parcelable接口。
b.Serializable接口和Parcelable接口的比较:
c.serialVersionUID
含义:是Serializable接口中用来辅助序列化和反序列化过程。 注意:原则上序列化后的数据中的serialVersionUID要和当前类的serialVersionUID 相同才能正常的序列化。
注意:两种变量不会参与序列化过程:
- 静态成员变量属于类,不属于对象。
- 用transient关键字标记的成员变量。
二、IPC方式
1、使用Bundle
a.Bundle
支持在Activity、Service和Receiver之间通过Intent.putExtra()传递Bundle数据。
b.原理:Bundle实现Parcelable接口,它可方便的在不同的进程中传输。
c.注意:Bundle不支持的数据类型无法在进程中被传递。
思考下面这种情况:
Q:在A进程进行计算后的结果不是Bundle所支持的数据类型,该如何传给B进程?
A:将在A进程进行的计算过程转移到B进程中的一个Service( 比如IntentService )里去做,这样可成功避免进程间的通信问题。
2、使用文件共享
a.文件共享:两个进程通过读/写同一个文件来交换数据。比如A进程把数据写入文件,B进程通过读取这个文件来获取数据。
b.适用情况:对数据同步要求不高的进程之间进行通信,并且要妥善处理并发读/写的问题。
c.虽然SharedPreferences也是文件存储的一种,但不建议采用。
原因:系统对SharedPreferences的读/写有一定的缓存策略,即在内存中有一份该文件的缓存,因此在多进程模式下,其读/写会变得不可靠,甚至丢失数据。