You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:22:54