Serializable和Parcelable总结

来源:互联网 发布:淘宝个人信誉度怎么看 编辑:程序博客网 时间:2024/06/07 16:18

本文是学习《Android开发艺术探索》的记录摘要

Serializable

  • Serializable是Java提供的序列化接口
  • serialVersionUID这个最好加上,如果不手动加,系统会重新计算当前类的hash值并赋值给serialVersionUID。当对象添加或删除了属性,如果没有serialVersionUID,就会反序列化失败,如果有serialVersionUID,程序就能最大限度的反序列化。
  • 静态成员变量不属于对象,所以不会被序列化
  • 如果需要某些变量不参与序列化,使用transient修饰,比如密码之类的。在kotlin中,使用如下方式:
data class User(var userId: Int, @Transient var userName: String, var isMale: Boolean) : Serializable {    val serialVersionUID = 12345678912345L}

Parcelable

方法 解释 createFromParcel(Parcel in) 从序列化后的对象中创建原始对象 new Array(int size) 创建指定长度的原始对象数组 writeToParcel(Parcel out,int flag) 将当前对象写入序列化结构中,flag有两个值:0和1,1表示当前对象需要作为返回值返回,不能立即释放资源,一般用0 describeContents() 返回当前对象的内容描述,如果含有文件描述符,返回1,一般用0
  • 系统已经提供了很多实现Parcelable的类,Intent,Bundle,Bitmap,List,Map,如果要使List和Map可以序列化,需它们里面的对象可以被序列化
  • writeToParcel()写入的顺序要和createFromParcel()的顺序一致
class Person : Parcelable {    var id: Int = 0    var name: String = ""    var isMale = true    var book: Book? = null    constructor(id: Int, name: String, isMale: Boolean, book: Book) {        this.id = id        this.name = name        this.isMale = isMale        this.book = book    }    constructor(parcel: Parcel) {        this.id = parcel.readInt()        this.name = parcel.readString()        this.isMale = parcel.readInt() == 1        this.book = parcel.readParcelable(Thread.currentThread().contextClassLoader)    }    override fun writeToParcel(dest: Parcel?, flags: Int) {        val male = if (isMale) 1 else 0        dest?.writeInt(id)        dest?.writeString(name)        dest?.writeInt(male)        dest?.writeParcelable(book, 0)    }    override fun describeContents(): Int = 0    companion object CREATOR : Parcelable.Creator<Person> {        override fun createFromParcel(parcel: Parcel): Person {            return Person(parcel)        }        override fun newArray(size: Int): Array<Person?> {            return arrayOfNulls(size)        }    }}

Serializable和Parcelable区别

  • Serializable是由Java提供,Parcelable是由Android提供,它俩都能用于Intent传递数据
  • Serializable使用简单,但开销大,序列化和反序列化需要大量IO操作,需要将对象序列化存储到设备中,或者将对象序列化通过网络传输时使用
  • Parcelable主要用于内存序列化,效率高

readFromParcel()

在使用AIDL传递自定义Parcelable对象,并且使用out或inout定向tag时,会发现找不到readFromParcel()方法,需要手动在Parcelable对象中实现该方法,但为什么不能被标记成override就不知道了,觉得很奇怪

fun readFromParcel(parcel: Parcel) {    this.id = parcel.readInt()    this.name = parcel.readString()    this.isMale = parcel.readInt() == 1    this.book = parcel.readParcelable(Thread.currentThread().contextClassLoader)}
原创粉丝点击