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

如何正确实现含ArrayList<Object>的Parcelable?自定义类列表传参报错求解

解决自定义类ArrayList的Parcelable传递问题

首先咱们得明确核心规则:所有要通过Parcelable传递的自定义类(包括嵌套的内部类)都必须实现Parcelable接口,而且绝对不能传递无法序列化的对象——比如你ConfigStruct里的View,它和UI上下文强绑定,根本没法被Parcel序列化,必须先处理掉。

第一步:给基础类实现Parcelable

先从最底层的Lists类入手,完成它的Parcelable实现:

public class Lists implements Parcelable {
    String name_opt;
    byte[] value;

    // 普通构造函数
    public Lists(String name_opt, byte[] value) {
        this.name_opt = name_opt;
        this.value = value;
    }

    // 从Parcel读取数据的构造函数
    protected Lists(Parcel in) {
        name_opt = in.readString();
        value = in.createByteArray();
    }

    @Override
    public int describeContents() {
        return 0; // 非文件描述符场景返回0即可
    }

    // 把数据写入Parcel
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name_opt);
        dest.writeByteArray(value);
    }

    // 静态CREATOR,必须实现的Parcelable组件
    public static final Creator<Lists> CREATOR = new Creator<Lists>() {
        @Override
        public Lists createFromParcel(Parcel in) {
            return new Lists(in);
        }

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

第二步:处理ConfigStruct的Parcelable实现

接下来处理ConfigStruct(或者你用的ConfigStructParcelable包装类),注意两个关键细节:

  1. 把View标记为transient(不会被序列化),因为View传递后无法复用,建议在接收方重新初始化
  2. 对List<Lists>用Parcelable标准的writeTypedList和readTypedList方法处理

示例代码:

public class ConfigStruct implements Parcelable {
    String page;
    String name;
    String type;
    byte[] val_size;
    byte[] max_lenght;
    byte[] min_lenght;
    byte[] value;
    List<Lists> list;
    // 标记为transient,跳过序列化
    transient View view;

    // 普通构造函数
    public ConfigStruct(String page, String name, String type, byte[] val_size, byte[] max_lenght, byte[] min_lenght, byte[] value, List<Lists> list, View view) {
        this.page = page;
        this.name = name;
        this.type = type;
        this.val_size = val_size;
        this.max_lenght = max_lenght;
        this.min_lenght = min_lenght;
        this.value = value;
        this.list = list;
        this.view = view;
    }

    // Parcel读取构造函数
    protected ConfigStruct(Parcel in) {
        page = in.readString();
        name = in.readString();
        type = in.readString();
        val_size = in.createByteArray();
        max_lenght = in.createByteArray();
        min_lenght = in.createByteArray();
        value = in.createByteArray();
        // 读取Parcelable列表
        list = new ArrayList<>();
        in.readTypedList(list, Lists.CREATOR);
        // view无需读取,接收方自行初始化
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(page);
        dest.writeString(name);
        dest.writeString(type);
        dest.writeByteArray(val_size);
        dest.writeByteArray(max_lenght);
        dest.writeByteArray(min_lenght);
        dest.writeByteArray(value);
        // 写入Parcelable列表
        dest.writeTypedList(list);
        // view无需写入
    }

    public static final Creator<ConfigStruct> CREATOR = new Creator<ConfigStruct>() {
        @Override
        public ConfigStruct createFromParcel(Parcel in) {
            return new ConfigStruct(in);
        }

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

第三步:正确实现包含ArrayList的Parcelable

这里要划重点:Object必须是实现了Parcelable的类,否则Parcelable无法处理(如果是任意Object,建议改用Serializable,但效率会低一些)。

情况1:列表是统一类型的Parcelable子类

比如ArrayList<YourParcelableClass>,直接用writeTypedList和readTypedList:

// 写入
dest.writeTypedList(yourParcelableList);
// 读取
yourParcelableList = new ArrayList<>();
in.readTypedList(yourParcelableList, YourParcelableClass.CREATOR);

情况2:列表包含多种Parcelable子类

用writeParcelableList和readParcelableList,需要传入类加载器:

// 写入
dest.writeParcelableList(yourMixedParcelableList, flags);
// 读取
yourMixedParcelableList = in.readParcelableList(new ArrayList<>(), getClass().getClassLoader());

最后:传递数据的正确姿势

在页面间传递时:

// 发送方
Intent intent = new Intent(this, TargetActivity.class);
// 传递单个对象
intent.putExtra("single_config", yourConfigStructInstance);
// 传递列表
intent.putParcelableArrayListExtra("config_list", yourConfigStructList);
startActivity(intent);

// 接收方
ConfigStruct singleConfig = getIntent().getParcelableExtra("single_config");
ArrayList<ConfigStruct> configList = getIntent().getParcelableArrayListExtra("config_list");

内容的提问来源于stack exchange,提问作者Egor Vasilyev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:02:00