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()); } }
常见坑点提醒
- 忘记定义
CREATOR常量:这是最容易犯的错误,系统找不到CREATOR就会直接抛出BadParcelableException - 读写顺序不一致:writeToParcel里写的顺序和构造方法里读的顺序必须完全一样,不然字段值会错乱
- 嵌套Parcelable对象:如果你的类里包含其他自定义Parcelable对象,要使用
dest.writeParcelable()和in.readParcelable()来处理,不要直接读写字段 - 不要用Serializable替代:虽然Serializable也能传递对象,但Android官方推荐Parcelable,性能差很多
内容的提问来源于stack exchange,提问作者naima
相关产品推荐
相关产品推荐

