一、Android中的多进程模式
1、多进程的应用情况
- 一个应用因为自身的需要采用多进程模式来实现。
- 当前应用需要向其他应用获取数据,所以必须采用跨进程通信。
2、多进程模式的实现
- 正常情况:在Manifest.xml文件中为四大组件配置android:process属性。
- 特殊情况:通过JNI在native层fork一个新进程。
注意:
- android:process属性的值以”:”开头,表示在当前进程名前面加上当前包名,而且此进程属于当前进程的私有进程。
- android:process属性的值不以”:”开头,表示当前进程属于全局进程,其他应用可以通过ShareUID方式和它跑在同一进程中。
3、使用多进程会引发的问题
- 线程同步机制完全失效:因为不同进程在不同内存,所以锁对象和锁全局类无法保证线程同步。
- 静态成员和单例模式失效。
- SharePreferences的可靠性下降:因为SharePreferences并发写操作,这可能会导致数据的丢失。
- Application会多次创建:当一个组件在一个新进程中运行时,系统要在创建新的进程同时分配独立的虚拟机,所以就是启动了一个应用的进程,也就是创建了一个新的Application。
二、IPC基础概念介绍
1、Serializable接口
- 让实体类实现Serializable接口,并在类中声明serialVersionUID。
- 序列化过程:先初始化一个实体类对象user,然后初始化一个ObjectOutputStream类对象out,最后调用out.writeObject(user)。
- 反序列化过程:先初始化一个ObjectInputStream类对象in,最后调用in.readObject()为实体类对象赋值。
serialVersionUID的工作机制:序列化这个类对象时,系统会把当前类的serialVersionUID写入序列化的文件中,当反序列化的时候系统去检测文件中的serialVersionUID,如果它和当前类的serialVersionUID一致,则可以成功反序列化,否则就说明当前类和序列化的类相比发生了变换。
注意:
- 静态成员变量属于类不属于对象,所以不参与序列化过程。
- 用transient关键字标记的成员变量不参与序列化过程。
- 当版本升级后,新增、删除了某个变量,依然可以序列化成功,如果类结构发生非常规性变化,比如类名改变,尽管serialVersionUID验证通过,还是会失败。
2、Parcelable接口
- 让实体类实现Serializable接口。
- 序列化功能由writeToParcel方法实现。
- 反序列化功能由CREATOR完成。
- 内容描述功能由describeContents方法实现,几乎所有情况下这个方法都返回0,仅当当前对象中存在文件描述符时,此方法返回1。
3、Binder概念
- 从IPC角度来说,Binder是Android中的一种跨进程通信方式。
- 从Android框架角度来说,Binder是ServiceManager连接各种Manager和相应ManagerService的桥梁。
- 从Android应用层来讲,Binder是客户端和服务端进行通信的媒介,当bindService的时候,服务端会返回一个包含了服务端业务的Binder对象,通过这个Binder对象,客户端就可以获取服务端提供的服务和数据。
两个重要方法:
- linkToDeath:给Binder设置死亡代理,当Binder死亡时,我们就会收到通知,再进行连接请求。
- unLinkToDeath:声明一个DeathRecipient对象,实现binderDied方法,当Binder死亡时,移除Binder的死亡代理。