读书笔记:Android中的进程间通信(二)

阅读的书籍:《Android开发艺术探索》

关键词:Serializable,Parcelable,Serializable和Parcelable的区别,Binder

Serializable接口:java提供的一个序列化接口,为对象提供标准的序列化和反序列化操作

想让一个对象实现序列化,只需要这个类实现Serializable接口并声明一个serialVersionUID(非必需)即可

读书笔记:Android中的进程间通信(二)

如何进行对象的序列化和反序列化:

采用ObjectOutputStream和ObjectInputStream的writeObject方法和readObject方法

关于serialVersionUID

原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同才能够正常地被反序列化

serialVersionUID的工作机制:

  1. 序列化的时候系统会把当前类的serialVersionUID写入序列化的文件中,当反序列化的时候系统会去检测文件中的serialVersionUID是否和当前类的serialVersionUID一致
  2. 如果一致就说明序列化的类的版本和当前类的版本是相同的,即可成功反序列化,否则就说明发生了变化

当我们手动指定了serialVersionUID的值以后,就可以很大程度上避免反序列化过程的失败

特殊情况

如果类结构发生了毁灭性改变, 比如修改了类名或者成员变量的类型,这时尽管serialVersionUID验证通过了,反序列化过程也依然会失败

Parcelable接口:Android特有的,只要实现这个接口,一个类的对象就可以实现序列化并可以通过Intent和Binder传递

例子:

读书笔记:Android中的进程间通信(二)

读书笔记:Android中的进程间通信(二)

方法说明:

createFromParcel:从序列化后的对象中创建原始对象

newArray:创建指定长度的原始对象数组

User(Parcel parcel):从序列化后的对象中创建原始对象

writeToParcel(Parcel dest, int flags):将当前对象写入序列化结构中。flags为1时标识当前对象需要作为返回值返回

describeContents:返回当前对象的内容描述。如果含有文件描述符,返回1,否则返回0

Serializable和Parcelable的区别:

  • Serializable使用简单但是开销大,序列化和反序列化过程都需要大量I/O操作
  • Parcelable使用稍微麻烦,但效率很高

使用场景

  1. Parcelable:内存序列化
  2. Serializable:将对象序列化到存储设备中或者将对象序列化后通过网络传输

Binder:Binder是Android中的一个类,它实现了IBinder接口 

从Android应用层来说

Binder是客户端和服务端进行通信的媒介,当bindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,然后客户端通过这个Binder对象就额可以获取服务端提供的服务或数据

从Android FrameWork角度来说

Binder是ServiceManager连接各种Manager和对应ManagerService的桥梁

读书笔记:Android中的进程间通信(二)

Binder的工作机制图

读书笔记:Android中的进程间通信(二)

  • 当客户端发起远程请求时,当前线程会被挂起直到服务端进程返回数据
  • 如果一个远程方法时很耗时的,那么不能在UI线程中发起此远程请求
  • 服务端的Binder方法是运行在Binder的线程池中的,所以Binder方法要采用同步
  • 通过linkToDeath方法(对应unlinkToDeath)可以给Binder设置一个死亡代理,当Binder死亡时,能够收到通知进而重新发起连接请请求,恢复连接