序列化
IPC因为是在不同的进程中,数据传输需要使用序列化。Android中常用的序列化方式有两个
一、Serializable
1.1 serializable的读与写
写
User user = new User(0,"jake",true);
ObjectOutputStream out = new ObjectOutputStream(newFileOutputStream("cache.txt"));
out.writeObject(user);
out.close();
读
ObjectInputStream in = new ObjectInputStream( newFileInputStream("cache.txt"));
User newUser = (User) in.readObject();
in.close();
1.2 serialVersionUID
serialVersionUID是用来辅助序列化与反序列化的,如果写进去的serialVersionUID是1,后面重构代码,serialVersionUID = 2,此时解析就会报错
java.io.InvalidClassException: Main;
local class incompatible: stream
classdesc serialVersionUID = 8711368828010083044,local class serialVersionUID = 8711368828010083043。
那么,是否只要serialVersionUID一样就可以了呢,如果只是增删成员方法和变量,是可以最大程度的还原的。但是如果我们直接修改了类的名字,那也会还原失败
二、Parcelable
2.1 Parcelable的读与写
最简单的Parcelable读写例子
data class User(var userName: String?, var age:Int):Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readInt()
) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(userName)
parcel.writeInt(age)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<User> {
override fun createFromParcel(parcel: Parcel): User {
return User(parcel)
}
override fun newArray(size: Int): Array<User?> {
return arrayOfNulls(size)
}
}
}
读
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readInt()
) {
}
写
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(userName)
parcel.writeInt(age)
}
这里的flags需要注意
| 取值范围 | 标记位 | 含义 |
|---|---|---|
| 0或1 | PARCELABLE_WRITE_RETURN_VALUE | 1表示需要作为返回值返回,不能立即释放,几乎所有情况为0 |
2.2 Parcelable的describeContents
| 取值范围 | 标记位 | 含义 |
|---|---|---|
| 0或1 | CONTENTS_FILE_DESCRIPTOR | 如果包含文件描述符,返回1,否则返回0 |
三、Serializable和Parcelable使用场景
3.1 Serializable
开销较大,序列化和反序列化有大量的I/O操作,适用于跨设备的传输
3.2 Parcelable
使用起来稍麻烦,但是效率较高,Android推荐使用