Android跨Activity传递Parcelable对象时解包异常求助
问题分析与解决方案
嘿,我来帮你搞定这个Parcelable传递的坑!你遇到的这个Unmarshalling unknown type code异常,根源其实是你的Account类的Parcelable实现不完整,导致整个Intent的Bundle数据结构被破坏了,哪怕你先读取list_size这个int值,系统解析Bundle时已经因为损坏的Parcel数据报错了。
为什么会出问题?
你看你的Account类里有多个Set类型的成员变量(followedAccountsIds、likedTagsIds这些),但在writeToParcel方法里只写入了accountId和accountName,从Parcel构造对象的protected Account(Parcel in)方法也只读取了这两个字段。当你把Account对象放进Intent Extra时,Parcel里的实际数据和系统预期的结构完全不匹配,直接导致了解析崩溃。
两步解决问题
第一步:完整实现Account的Parcelable逻辑
要把所有成员变量都纳入序列化/反序列化流程,包括那些Set集合。注意不同类型的Set要对应不同的Parcel读写方法,另外你的Post类也必须实现Parcelable接口(否则Post集合无法序列化)。
修改后的Account类代码:
import android.os.Parcel; import android.os.Parcelable; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; public class Account implements Parcelable { private Long accountId; private String accountName; private Set<String> followedAccountsIds = new HashSet<>(); private Set<String> followersAccountsIds = new HashSet<>(); private Set<Integer> likedTagsIds = new HashSet<>(); private Set<Post> postsByAccount = new HashSet<>(); public Account() { } public Account(Long accountId, String accountName, Set<String> followedAccountsIds, Set<String> followersAccountsIds, Set<Integer> likedTagsIds, Set<Post> postsByAccount) { this.accountId = accountId; this.accountName = accountName; this.followedAccountsIds = followedAccountsIds; this.followersAccountsIds = followersAccountsIds; this.likedTagsIds = likedTagsIds; this.postsByAccount = postsByAccount; } // 省略getter和setter protected Account(Parcel in) { // 读取accountId,处理null情况 if (in.readByte() == 0) { accountId = null; } else { accountId = in.readLong(); } accountName = in.readString(); // 读取String类型的Set followedAccountsIds = new HashSet<>(in.createStringArrayList()); followersAccountsIds = new HashSet<>(in.createStringArrayList()); // 读取Integer类型的Set(先转数组再转Set) Integer[] likedTagsArray = in.createIntArray(); if (likedTagsArray != null) { likedTagsIds = new HashSet<>(Arrays.asList(likedTagsArray)); } // 读取Post集合(需Post实现Parcelable) List<Post> postList = in.createTypedArrayList(Post.CREATOR); if (postList != null) { postsByAccount = new HashSet<>(postList); } } public static final Creator<Account> CREATOR = new Creator<Account>() { @Override public Account createFromParcel(Parcel in) { return new Account(in); } @Override public Account[] newArray(int size) { return new Account[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int flags) { // 写入accountId,处理null情况 if (accountId == null) { parcel.writeByte((byte) 0); } else { parcel.writeByte((byte) 1); parcel.writeLong(accountId); } parcel.writeString(accountName); // 写入String Set(转成ArrayList) parcel.writeStringList(new ArrayList<>(followedAccountsIds)); parcel.writeStringList(new ArrayList<>(followersAccountsIds)); // 写入Integer Set(转成数组) parcel.writeIntArray(likedTagsIds.toArray(new Integer[0])); // 写入Post集合(转成ArrayList) parcel.writeTypedList(new ArrayList<>(postsByAccount)); } }
第二步:简化Intent传递列表的方式
不用逐个putExtra传递Account对象,Intent支持直接传递ArrayList<? extends Parcelable>,代码更简洁还不容易出错。
- Activity A修改后的代码:
Intent intent = new Intent(ActivityA.this, ActivityB.class); // 把Set转成ArrayList(因为Set不能直接序列化) intent.putParcelableArrayListExtra("account_list", new ArrayList<>(accountList)); startActivityForResult(intent, 2);
- Activity B修改后的代码:
private void init() { Intent intent = getIntent(); // 直接获取Parcelable列表 List<Account> newList = intent.getParcelableArrayListExtra("account_list"); // 记得做判空处理 if (newList != null) { // 这里处理你的业务逻辑即可 } }
这样修改后,既修复了Parcelable序列化不完整的问题,又简化了数据传递的代码,异常自然就消失了。
内容的提问来源于stack exchange,提问作者cod3min3
相关产品推荐
相关产品推荐

