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

Parcelable类内列表读取异常:Activity间传参列表数量不符

解决Activity间传递Parcelable对象时列表数据暴增的问题

兄弟,这种A里明明是2条数据,传到B里变成700多万条的情况,我之前也踩过同款坑!大概率是你Parcelable的读写逻辑出了问题,尤其是ArrayList字段的处理和读写顺序的匹配,我给你一步步捋清楚:

核心问题原因

Parcelable的工作原理是把对象序列化到内存块里,再从内存块反序列化回来。如果写入字段的顺序和读取字段的顺序不一致,或者ArrayList的读写方法用错了,Parcel就会把内存里的垃圾数据当成有效数据读进来,直接导致列表长度爆炸。

给你一套正确的实现模板

针对你的Assessment类(包含ArrayList<Photo>,且Photo也实现Parcelable),我写了一份标准实现,你对照着改:

Assessment类的正确Parcelable实现

public class Assessment extends BaseObservable implements Parcelable {
    @SerializedName("Vehicle")
    private String vehicle;
    // 你的图片列表字段
    private ArrayList<Photo> photos;

    // 空构造器
    public Assessment() {}

    // 从Parcel反序列化的构造器
    protected Assessment(Parcel in) {
        // 读取顺序必须和writeToParcel里的写入顺序完全一致!
        vehicle = in.readString();
        // 读取Parcelable类型的列表,必须用readTypedList
        photos = new ArrayList<>();
        in.readTypedList(photos, Photo.CREATOR);
    }

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

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

    @Override
    public int describeContents() {
        return 0; // 没有特殊内容(比如FileDescriptor),返回0即可
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // 写入顺序要和构造器里的读取顺序严格对应!
        dest.writeString(vehicle);
        // 写入Parcelable列表用writeTypedList
        dest.writeTypedList(photos);
    }

    // Photo类的正确Parcelable实现也不能错
    public static class Photo implements Parcelable {
        private String photoUrl;
        // 其他字段...

        public Photo() {}

        protected Photo(Parcel in) {
            photoUrl = in.readString();
            // 其他字段读取顺序要和writeToParcel一致
        }

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

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

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

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(photoUrl);
            // 其他字段写入顺序要和构造器读取一致
        }
    }
}

关键错误点排查

你可以对照自己的代码检查这几个地方:

  • 字段读写顺序是否完全一致:比如你在writeToParcel里先写了photos再写vehicle,但构造器里先读了vehicle再读photos,这绝对会出问题!顺序必须丝毫不差。
  • ArrayList的读写方法是否正确:别用writeList和readList,对于Parcelable类型的列表,一定要用writeTypedList和readTypedList,这两个方法专门为Parcelable元素设计,不会出类加载器的问题。
  • Photo类的Parcelable实现是否正确:如果Photo类的读写顺序乱了,或者CREATOR写错了,也会导致整个列表读取异常。
  • 传递和接收的代码是否正确:
    Activity A里传递:
    Intent intent = new Intent(A.this, B.class);
    intent.putExtra("KEY_ASSESSMENT", yourAssessmentObject);
    startActivity(intent);
    
    Activity B里接收(Android 33+要加类加载器):
    // Android 33及以上
    Assessment assessment = getIntent().getParcelableExtra("KEY_ASSESSMENT", Assessment.class);
    // 低版本
    Assessment assessment = getIntent().getParcelableExtra("KEY_ASSESSMENT");
    

偷懒小技巧

如果字段太多怕写错顺序,可以用Android Studio的Parcelable插件自动生成代码,比如Parcelable Code Generator,右键类名→Generate→Parcelable,一键生成正确的代码,避免手动踩坑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:32:32