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

Android开发:如何在Parcelable中读写Double类型列表?

解决Parcelable中Double类型列表的读写问题

你代码里的核心问题出在Double列表的读取逻辑上——你调用了in.readValue()但没有把返回值赋值给mLl,而且用readValue处理List并不是Parcelable规范的做法。下面给你两种可靠的修正方案:


方案一:用Parcel的readList()/writeList()直接处理

Parcel专门提供了针对List的读写方法,对于包装类型的List(比如ArrayList<Double>),只要传入正确的类加载器就能正常工作:

修正后的完整代码

public class CinemasModel implements Parcelable {
    @SerializedName("ll")
    private ArrayList<Double> mLl;
    @SerializedName("films")
    private List<FilmsModel> mFilms;

    // 从Parcel读取的构造函数
    protected CinemasModel(Parcel in) {
        // 初始化Double列表,用readList填充数据
        mLl = new ArrayList<>();
        in.readList(mLl, Double.class.getClassLoader());
        
        // FilmsModel列表读取(注意FilmsModel必须也实现Parcelable)
        mFilms = new ArrayList<>();
        in.readList(mFilms, FilmsModel.class.getClassLoader());
    }

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

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

    // 其他构造函数保持不变
    public CinemasModel(ArrayList<Double> ll, List<FilmsModel> films) {
        this.mLl = ll;
        this.mFilms = films;
    }

    public CinemasModel() {
    }

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

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        // 直接用writeList写入Double列表
        if (mLl != null) {
            parcel.writeList(mLl);
        }
        parcel.writeList(mFilms);
    }
}

关键改动说明

  • 读取mLl时,调用in.readList(mLl, Double.class.getClassLoader()),把Parcel中的数据直接填充到初始化好的mLl列表中
  • 写入时增加了非空判断,避免mLl为null时触发空指针异常
  • 注意:如果你的FilmsModel还没实现Parcelable,一定要补上,否则mFilms的读写会失败

方案二:转换成double数组读写(更高效)

因为Double是基本类型double的包装类,我们可以把ArrayList<Double>转成double[]来读写,这种方式比直接读写List更高效,适合数据量较大的场景:

修正后的核心代码

// writeToParcel方法修改
@Override
public void writeToParcel(Parcel parcel, int i) {
    // 把Double列表转成double数组写入
    if (mLl != null && !mLl.isEmpty()) {
        double[] llArray = new double[mLl.size()];
        for (int j = 0; j < mLl.size(); j++) {
            llArray[j] = mLl.get(j);
        }
        parcel.writeDoubleArray(llArray);
    } else {
        // 写入空数组标记
        parcel.writeDoubleArray(null);
    }
    parcel.writeList(mFilms);
}

// 构造函数修改
protected CinemasModel(Parcel in) {
    // 读取double数组并转成ArrayList<Double>
    double[] llArray = in.createDoubleArray();
    if (llArray != null) {
        mLl = new ArrayList<>();
        for (double d : llArray) {
            mLl.add(d);
        }
    } else {
        mLl = new ArrayList<>();
    }
    
    mFilms = new ArrayList<>();
    in.readList(mFilms, FilmsModel.class.getClassLoader());
}

优点

  • 基本类型数组的序列化/反序列化效率比包装类List更高
  • 避免了类加载器可能带来的潜在问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:24:50