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

Android报错求助:Parcelable协议要求类实现Parcelable接口

解决android.os.BadParcelableException的问题

嘿,这个错误我之前踩过坑!BadParcelableException 本质就是你要传递的某个类声称实现了Parcelable接口,但没完全遵守Parcelable的协议规范,系统在尝试序列化/反序列化这个对象的时候就报错了。

核心原因

你要传递的类必须严格实现Parcelable的所有要求:

  • 实现Parcelable接口
  • 重写describeContents()和writeToParcel()方法
  • 必须定义一个名为CREATOR的静态常量,类型是Parcelable.Creator<T>

正确的Parcelable实现示例

下面给你一个完整的示例类,照着这个写就不会错:

public class User implements Parcelable {
    // 示例字段
    private String userName;
    private int userAge;
    private boolean isVip;

    // 普通构造方法
    public User(String userName, int userAge, boolean isVip) {
        this.userName = userName;
        this.userAge = userAge;
        this.isVip = isVip;
    }

    // 反序列化用的构造方法,必须从Parcel读取字段
    protected User(Parcel in) {
        // 注意:读取顺序必须和writeToParcel里的写入顺序完全一致!
        userName = in.readString();
        userAge = in.readInt();
        isVip = in.readByte() != 0; // boolean转byte存储,读取时转回来
    }

    // 必须的CREATOR常量,系统靠它来创建对象实例
    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

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

    @Override
    public int describeContents() {
        // 一般返回0即可,只有当类包含特殊对象(比如FileDescriptor)时才需要返回其他值
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // 写入字段的顺序要和上面构造方法的读取顺序一一对应!
        dest.writeString(userName);
        dest.writeInt(userAge);
        dest.writeByte((byte) (isVip ? 1 : 0));
    }

    // 可选:添加getter方法方便使用
    public String getUserName() { return userName; }
    public int getUserAge() { return userAge; }
    public boolean isVip() { return isVip; }
}

在Activity之间传递这个对象的示例

发送方Activity:

// 创建对象
User myUser = new User("Naima", 28, true);
// 封装到Intent里
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("USER_DATA", myUser);
// 启动目标Activity
startActivity(intent);

接收方MainActivity的onCreate方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 读取传递过来的对象
    if (getIntent() != null && getIntent().hasExtra("USER_DATA")) {
        User receivedUser = getIntent().getParcelableExtra("USER_DATA");
        // 这里就可以用receivedUser的字段了,比如Log输出
        Log.d("MainActivity", "用户名:" + receivedUser.getUserName());
    }
}

常见坑点提醒

  1. 忘记定义CREATOR常量:这是最容易犯的错误,系统找不到CREATOR就会直接抛出BadParcelableException
  2. 读写顺序不一致:writeToParcel里写的顺序和构造方法里读的顺序必须完全一样,不然字段值会错乱
  3. 嵌套Parcelable对象:如果你的类里包含其他自定义Parcelable对象,要使用dest.writeParcelable()和in.readParcelable()来处理,不要直接读写字段
  4. 不要用Serializable替代:虽然Serializable也能传递对象,但Android官方推荐Parcelable,性能差很多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:13:05