嵌套Parcelable通过Intent传递时出现解包错误求助
Android Intent传递嵌套Parcelable ArrayList时解包失败问题
我开发Android应用时,需要通过Intent传递包含嵌套Parcelable对象的ArrayList(具体为public ArrayList<FolderModel> folderList_),但从Intent中取出数据时出现如下错误:
Parcel android.os.Parcel@9aa641d: Unmarshalling unknown type code 6881389 at offset 1696.
奇怪的是,若注释掉ExerciseModel的writeToParcel方法中的folderName_字段,就能正常运行。经测试,单独传递ExerciseModel的ArrayList无问题,推测问题出在FolderModel或其内部的ArrayList中。
核心代码
FolderModel类
public class FolderModel implements Parcelable { String folderName_ = "Folder"; Boolean extended_ = false; ArrayList<ExerciseModel> exerciseList_; public FolderModel(String folderName, Boolean extended, ArrayList<ExerciseModel> exerciseList) { folderName_ = folderName; extended_ = extended; exerciseList_ = exerciseList; } protected FolderModel(Parcel in) { folderName_ = in.readString(); byte tmpExtended_ = in.readByte(); extended_ = tmpExtended_ == 0 ? null : tmpExtended_ == 1; exerciseList_ = in.createTypedArrayList(ExerciseModel.CREATOR); } public static final Creator<FolderModel> CREATOR = new Creator<FolderModel>() { @Override public FolderModel createFromParcel(Parcel in) { return new FolderModel(in); } @Override public FolderModel[] newArray(int size) { return new FolderModel[size]; } }; public String getFolderName_() { return folderName_; } public Boolean getExtended_() { return extended_; } public void setExtended_(boolean extended) { extended_ = extended; } public List<ExerciseModel> getExerciseList_() { return exerciseList_; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(folderName_); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { parcel.writeParcelableList(exerciseList_, i); } } }
ExerciseModel类
public class ExerciseModel implements Parcelable { String exerciseName_; String description_; String folderName_; public ExerciseModel(String exerciseName, String description, String folderName) { exerciseName_ = exerciseName; description_ = description; folderName_ = folderName; } protected ExerciseModel(Parcel in) { exerciseName_ = in.readString(); description_ = in.readString(); folderName_ = in.readString(); } public static final Creator<ExerciseModel> CREATOR = new Creator<ExerciseModel>() { @Override public ExerciseModel createFromParcel(Parcel in) { return new ExerciseModel(in); } @Override public ExerciseModel[] newArray(int size) { return new ExerciseModel[size]; } }; public String getExerciseName_() { return exerciseName_; } public String getDescription_() { return description_; } public String getFolderName_() { return folderName_; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(exerciseName_); parcel.writeString(description_); parcel.writeString(folderName_); } }
问题原因与修复
问题根源
- 字段读写不匹配:
FolderModel的Parcel读取逻辑中读了extended_的byte值,但writeToParcel完全没写入该字段,导致Parcel数据顺序错位。 - 列表读写方法不兼容+版本判断错误:读列表用
createTypedArrayList,但写的时候仅在API Q+用writeParcelableList,两者不配对;低版本直接丢失exerciseList_数据,解包时却尝试读取,进一步加剧错位。ExerciseModel多写入一个字段时,错位的影响触发了未知类型码错误。
修复后的FolderModel.writeToParcel方法
@Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(folderName_); // 对应读逻辑,写入extended_的byte值 parcel.writeByte((byte) (extended_ == null ? 0 : extended_ ? 1 : 2)); // 使用与createTypedArrayList配对的writeTypedList,全版本兼容 parcel.writeTypedList(exerciseList_); }
修复说明
- 严格保证写入字段的顺序、数量和读取逻辑完全一致,这是Parcelable实现的核心要求。
writeTypedList和createTypedArrayList是配套方法,全版本兼容,无需API版本判断,避免低版本丢失数据。
内容的提问来源于stack exchange,提问作者Louckas
相关产品推荐
相关产品推荐

