-
parcel 序列化过程中的几种问题及解决办法.
1.1 Parcel 序列化集合 List。
parcel.readTypedList(List list, Creator c) 这里需要注意 list不能为null,否则会报空指针的错误。因此在从序列化读取之前,需要先做一个非空的判断。1.2 Parcel 序列化数组 String[]。
在createFromParcel 方法中,从Parcel 读取String[] 的时候,为什么parcel.readStringArray(String[] val) 会报错误呢?这里还是引用 stackoverflow 的解决方法吧。(http://stackoverflow.com/questions/14385253/how-to-use-writestringarray-and-readstringarray-in-a-parcel)简单来说就是,如果要使用parcel.readStringArray(selectedImage),你需要知道数组的准确长度并且手动分配它。因此在这里可以使用 parcel.createStringArray()。
1.3 Parcel 序列化布尔类型 boolean
Parcel 并没有提供直接序列化boolean 的方法, 但是依旧有处理方法,可以转化为btye类型来达到我们的目的。同样,代码也比较好理解。读:isSelected = source.readByte() != 0;
写:dest.writeByte((byte) (isSelected ? 1 : 0)); -
代码示例
public class PhotoImageBucket implements Parcelable {
public int count;
public String bucketName;
public PhotoImageItem special;
public List<PhotoImageItem> imageList;
public String[] selectedImage;
public PhotoImageBucket() {
super();
}
public PhotoImageBucket(Parcel source) {
super();
count = source.readInt();
bucketName = source.readString();
special = source.readParcelable(PhotoImageItem.class.getClassLoader());
// 注: readTypedList(List<PhotoImageItem> list, Creator<PhotoImageItem> c),这里 list不能为空,否则回报 NullPointException
if(imageList ==null){
imageList = new ArrayList<PhotoImageItem>();
}
source.readTypedList(imageList, PhotoImageItem.CREATOR);
// 注:这里为什么是parcel.createStringArray() 而不是 parcel.readStringArray(selectedImage)?
selectedImage = source.createStringArray();
}
public static Parcelable.Creator<PhotoImageBucket> CREATOR = new Creator<PhotoImageBucket>() {
@Override
public PhotoImageBucket[] newArray(int size) {
return new PhotoImageBucket[size];
}
@Override
public PhotoImageBucket createFromParcel(Parcel source) {
return new PhotoImageBucket(source);
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(count);
dest.writeString(bucketName);
dest.writeParcelable(special, flags);
dest.writeTypedList(imageList);
dest.writeStringArray(selectedImage);
}
}
public class PhotoImageItem implements Parcelable {
public String imageId;
public String imagePath;
public boolean isSelected = false;
public PhotoImageItem() {
}
public PhotoImageItem(Parcel source) {
imageId = source.readString();
imagePath = source.readString();
// 注:boolean 值的序列化方法
isSelected = source.readByte() != 0;
}
public static Parcelable.Creator<PhotoImageItem> CREATOR = new Creator<PhotoImageItem>() {
@Override
public PhotoImageItem[] newArray(int size) {
return new PhotoImageItem[size];
}
@Override
public PhotoImageItem createFromParcel(Parcel source) {
return new PhotoImageItem(source);
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(imageId);
dest.writeString(imagePath);
// 注:boolean 值的序列化方法
dest.writeByte((byte) (isSelected ? 1 : 0));
}
}
3.疑问
- Parcelables: writeTypedArray(T[], int), writeTypedList(List), readTypedArray(T[], android.os.Parcelable.Creator) and readTypedList(java.util.List, android.os.Parcelable.Creator). These methods do not write the class information of the original object. 最后一句可以翻译为不写原始对象的类信息? 不知道是不是翻译的不准确,总之不太理解这句话的意思。