Parcelabel序列化后写入内存,因此比 Serializable更高效,但是其序列化和反序列化都需要开发者主动实现。实现原理十分简单:按照被序列化的对象的属性顺序依次写入内存指定区,然后反序列化时按照同样的顺序进行读取。
关于异常java.lang.RuntimeException: Parcel android.os.Parcel: Unmarshalling unknown type code。主要有两种原因造成。
1.(未亲测)。序列化属性有null值,尤其注意一些复杂类型属性(除int,long,byte,char等简单类型外).List类型属性如果为null则可给一个空List集合
2.序列化属性读写时类型不一。
第2个原因看起来简单实则与序列化对象的属性息息相关。序列化方法有很多:
writeLong,writeString,writeByte,writeValue等不一而足,反序列化对应有
readLong,readString,readByte,readValue等
其中writeLong和readLong对应是简单数据类型的long值,而不是long值的包装类Long.因此,虽然都知道了读写类型要对应,但是稍有大意就可能把Long类型的值用writeLong和readLong读写.String没有包装类,可以直接用writeString和readString读写。
下面简单总结写复杂类型读写:
包装类读写:Long,Integer等。不能用writeLong和readLong,而要用writeValue和readValue,这两个方法是读写对象的方法。
boolean值简单类型,可以使用byte代替,例如对于 boolean bValue:
写入: writeByte((byte)bValue?1:0)
读取: bValue=in.readByte==0?false:in.readByte==1;
其他属性暂未涉及,可以类推Long或等之后遇到再行补充.
实际例子:
对象属性类型及顺序列表:
private Long id;
private String gSerial;
private String controllerAddr;
private String deviceAddr;
private String name;
private String deviceType;
private String groupType;
private String deviceRegion;
private String curStatu;
private String curData;
private String controlType;
private Boolean isOnline;
private Boolean isDoubleSwitch;
序列化接口方法
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(id);
dest.writeString(gSerial);
dest.writeString(controllerAddr);
dest.writeString(deviceAddr);
dest.writeString(name);
dest.writeString(deviceType);
dest.writeString(groupType);
dest.writeString(deviceRegion);
dest.writeString(curStatu);
dest.writeString(curData);
dest.writeString(controlType);
dest.writeByte((byte) (isOnline?1:0));
dest.writeByte((byte) (isDoubleSwitch?1:0));
}
反序列化接口方法
protected Device(Parcel in) {
id= (Long) in.readValue(Long.class.getClassLoader());
gSerial = in.readString();
controllerAddr = in.readString();
deviceAddr = in.readString();
name = in.readString();
deviceType = in.readString();
groupType = in.readString();
deviceRegion = in.readString();
curStatu = in.readString();
curData = in.readString();
controlType = in.readString();
byte tmpIsOnline = in.readByte();
isOnline = tmpIsOnline == 0 ? false : tmpIsOnline == 1;
byte tmpIsDoubleSwitch = in.readByte();
isDoubleSwitch = tmpIsDoubleSwitch == 0 ? false : tmpIsDoubleSwitch == 1;
}
public static final Creator<Device> CREATOR = new Creator<Device>() {
@Override
public Device createFromParcel(Parcel in) {
return new Device(in);
}
@Override
public Device[] newArray(int size) {
return new Device[size];
}
};
网友评论