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

MPAndroidChart中Activity间传递BarEntry报错:无法打包非可打包数据

解决Android传递BarEntry时的ParcelFormatException问题

这个错误android.os.ParcelFormatException: Cannot parcel an Entry with non-parcelable data的核心原因是:你使用的MPAndroidChart的BarEntry类虽然本身实现了Parcelable,但它携带的自定义data(也就是你传入的"Jan"、"Feb"这类字符串)在Parcel序列化过程中不被系统认可——MPAndroidChart的Entry基类在处理data字段时,要求它必须是Parcelable类型,否则就会抛出这个异常。而你用putSerializable传递集合时,底层依然会尝试用Parcel机制处理BarEntry对象,从而触发错误。

下面给你几个可行的解决方案:

方案一:拆分数据传递,在目标Activity重新绑定标签

这是最简单的方案,不需要修改BarEntry类:

  1. 在发送方(ChartRevenueActivity),把月份标签单独提取为一个数组,和BarEntry集合一起传递:
ArrayList<BarEntry> barEntries = new ArrayList<>();
// 初始化barEntries的代码不变...

// 提取月份列表
ArrayList<String> monthLabels = new ArrayList<>();
monthLabels.add("Jan");
monthLabels.add("Feb");
monthLabels.add("Mar");
// ... 补充剩余月份

Intent barIntent = new Intent(ChartRevenueActivity.this, FullscreenActivity.class);
// 用putParcelableArrayListExtra传递BarEntry(因为BarEntry本身是Parcelable)
barIntent.putParcelableArrayListExtra("barEntries", barEntries);
barIntent.putStringArrayListExtra("monthLabels", monthLabels);
barIntent.putExtra("type", "barChart");
startActivity(barIntent);
  1. 在接收方(FullscreenActivity),重新给每个BarEntry绑定标签:
// 接收数据
ArrayList<BarEntry> barEntries = getIntent().getParcelableArrayListExtra("barEntries");
ArrayList<String> monthLabels = getIntent().getStringArrayListExtra("monthLabels");

// 重新绑定data字段
if (barEntries != null && monthLabels != null && barEntries.size() == monthLabels.size()) {
    for (int i = 0; i < barEntries.size(); i++) {
        barEntries.get(i).setData(monthLabels.get(i));
    }
}

// 后续设置BarChart的代码不变...

方案二:自定义Parcelable的BarEntry子类

如果需要直接传递带data的BarEntry,可以自定义子类手动处理data的Parcel逻辑:

public class CustomBarEntry extends BarEntry implements Parcelable {

    public CustomBarEntry(float x, float[] y, Object data) {
        super(x, y, data);
    }

    // 从Parcel构造对象
    protected CustomBarEntry(Parcel in) {
        super(in);
        // 这里假设data是String,直接读取字符串
        setData(in.readString());
    }

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

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        // 写入data(这里强制转为String,根据你的实际类型调整)
        dest.writeString((String) getData());
    }
}

然后在发送方使用这个自定义类:

ArrayList<CustomBarEntry> barEntries = new ArrayList<>();
barEntries.add(new CustomBarEntry(0, new float[]{8f, 9f, 10f}, "Jan"));
// ... 其他条目初始化

Intent barIntent = new Intent(ChartRevenueActivity.this, FullscreenActivity.class);
barIntent.putParcelableArrayListExtra("barEntries", barEntries);
barIntent.putExtra("type", "barChart");
startActivity(barIntent);

接收方直接接收:

ArrayList<CustomBarEntry> barEntries = getIntent().getParcelableArrayListExtra("barEntries");

方案三:移除不必要的data字段

如果你的图表不需要显示这些月份标签,或者可以通过其他方式(比如XAxis的ValueFormatter)设置标签,那直接去掉BarEntry构造的第三个参数即可,这样默认的BarEntry就能正常传递:

barEntries.add(new BarEntry(0, new float[]{8f, 9f, 10f})); // 去掉第三个参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:33:36