一、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的死亡代理。