Android序列化接口Parcelable异常:java.lang.RuntimeException: Parcel android.os.Parcel: Unmarshalling unkn...

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 CREATOR = new Creator() {
        @Override
        public Device createFromParcel(Parcel in) {
            return new Device(in);
        }

        @Override
        public Device[] newArray(int size) {
            return new Device[size];
        }
    };

你可能感兴趣的:(Android序列化接口Parcelable异常:java.lang.RuntimeException: Parcel android.os.Parcel: Unmarshalling unkn...)