android - 意图getextra中嵌套Parcelable的空指针异常
问题描述
我有一个嵌套的 parcelable 类(内部有 Provider 类的产品类)。我想将 Product 对象发送到另一个具有额外意图的活动。当我有意图时,提供者对象为空。
外部(父)类是产品(为方便起见省略了设置器和获取器):
public class Product implements Parcelable {
public static final String KEY_CART_COUNT = "KEY_CART_COUNT";
private int id;
private String title;
private String description;
@SerializedName("category_id")
private int categoryId;
@SerializedName("city_id")
private int cityId;
private String fee;
private String fee2;
@SerializedName("main_cat")
private Integer mainCategory;
@SerializedName("barcode_type")
private String barcodeType;
@SerializedName("barcode_text")
private String barcodeText;
private String unit;
private String image;
@SerializedName("is_active")
private int isActive;
@SerializedName("now")
private long now;
//*****************************************************************
@SerializedName("provider_info")
private Provider provider;
//*****************************************************************
@SerializedName("is_bookmarked")
private boolean isBookmarked;
@SerializedName("image_url")
private String imageUrl;
@SerializedName("exists_number")
private int existsNumber;
@SerializedName("buy_limit")
private int buyLimit;
private long addToCartTime;
private int cartCount;
protected Product(Parcel in) {
id = in.readInt();
title = in.readString();
description = in.readString();
categoryId = in.readInt();
cityId = in.readInt();
fee = in.readString();
fee2 = in.readString();
barcodeType = in.readString();
barcodeText = in.readString();
unit = in.readString();
image = in.readString();
isActive = in.readInt();
cartCount = in.readInt();
isBookmarked = in.readByte() != 0;
mainCategory = in.readInt();
imageUrl = in.readString();
existsNumber = in.readInt();
buyLimit = in.readInt();
addToCartTime = in.readLong();
provider = in.readParcelable(Provider.class.getClassLoader());
}
public Product() {
this.addToCartTime = Calendar.getInstance().getTime().getTime();
}
public Product(Product newProduct) {
this.id = newProduct.id;
this.title = newProduct.title;
this.description = newProduct.description;
this.categoryId = newProduct.categoryId;
this.cityId = newProduct.cityId;
this.fee = newProduct.fee;
this.fee2 = newProduct.fee2;
this.barcodeType = newProduct.barcodeType;
this.barcodeText = newProduct.barcodeText;
this.unit = newProduct.unit;
this.image = newProduct.image;
this.isActive = newProduct.isActive;
this.mainCategory = newProduct.mainCategory;
this.cartCount = newProduct.cartCount;
this.isBookmarked = newProduct.isBookmarked;
this.imageUrl = newProduct.imageUrl;
this.existsNumber = newProduct.existsNumber;
this.buyLimit = newProduct.buyLimit;
this.addToCartTime = newProduct.addToCartTime;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(title);
dest.writeString(description);
dest.writeInt(categoryId);
dest.writeInt(cityId);
dest.writeString(fee);
dest.writeString(fee2);
dest.writeString(barcodeType);
dest.writeString(barcodeText);
dest.writeString(unit);
dest.writeString(image);
dest.writeInt(isActive);
dest.writeInt(cartCount);
dest.writeInt(mainCategory);
dest.writeByte((byte) (isBookmarked ? 1 : 0));
dest.writeString(imageUrl);
dest.writeInt(existsNumber);
dest.writeInt(buyLimit);
dest.writeLong(addToCartTime);
dest.writeValue(provider);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Product> CREATOR = new Creator<Product>() {
@Override
public Product createFromParcel(Parcel in) {
return new Product(in);
}
@Override
public Product[] newArray(int size) {
return new Product[size];
}
};
}
这是我的 Provider 类:
public class Provider implements Parcelable {
public static final Creator<Provider> CREATOR = new Creator<Provider>() {
@Override
public Provider createFromParcel(Parcel in) {
return new Provider(in);
}
@Override
public Provider[] newArray(int size) {
return new Provider[size];
}
};
private int id;
@SerializedName("title")
private String title;
@SerializedName("description")
private String description;
@SerializedName("admin_id")
private int admin_id;
@SerializedName("provider_id")
private int provider_id;
@SerializedName("start1")
private String start1;
@SerializedName("start2")
private String start2;
@SerializedName("end1")
private String end1;
@SerializedName("end2")
private String end2;
protected Provider(Parcel in) {
id = in.readInt();
title = in.readString();
description = in.readString();
admin_id = in.readInt();
provider_id = in.readInt();
start1 = in.readString();
start2 = in.readString();
end1 = in.readString();
end2 = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(id);
parcel.writeString(title);
parcel.writeString(description);
parcel.writeInt(admin_id);
parcel.writeInt(provider_id);
parcel.writeString(start1);
parcel.writeString(end1);
parcel.writeString(start2);
parcel.writeString(end2);
}
}
将产品数组发送到 ProductDetailActivity 的代码:
Intent starter = new Intent(context, ProductDetailActivity.class);
starter.putParcelableArrayListExtra(Constants.ACTIVITY_EXTRA_PRODUCTS, new ArrayList<>(products));
context.startActivity(starter);
最后在 ProductDetailActivity 中获取产品:
getIntent().getParcelableArrayListExtra(Constants.ACTIVITY_EXTRA_PRODUCTS)
解决方案
正如laalto建议的那样,产品类(或任何 Parcelable 类)中的数据顺序在读写时应该相同。我将代码更改为此,它运行良好:
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(title);
dest.writeString(description);
dest.writeInt(categoryId);
dest.writeInt(cityId);
dest.writeString(fee);
dest.writeString(fee2);
dest.writeString(barcodeType);
dest.writeString(barcodeText);
dest.writeString(unit);
dest.writeString(image);
dest.writeInt(isActive);
dest.writeInt(cartCount);
dest.writeByte((byte) (isBookmarked ? 1 : 0));// Changed Order
dest.writeInt(mainCategory); // Changed Order
dest.writeString(imageUrl);
dest.writeInt(existsNumber);
dest.writeInt(buyLimit);
dest.writeLong(addToCartTime);
dest.writeLong(now);
dest.writeParcelable(provider, flags); // **Changed from writeValue to writeParcelable**
}
推荐阅读
- python-3.x - 表单发布后重定向时出现 Flask 错误 302
- c++ - gcc8 由于不可复制的类型而引发编译错误
- python - AES 简单函数 - 'int' 对象不可迭代
- apache-spark - 如何通过pyspark将十六进制数据插入Cassandra中的blob数据类型列
- python - 如何查看上次使用 python 更新私有 docker hub 存储库中的 docker 映像的时间
- r - R中两种密度混合的卷积
- sql - ballerina.io SQL LIKE 语句
- apache-kafka - .properties 文件中的变量?
- bash - 计算在线会议的总时间
- r - 使用日期序列,将一个数字除以一个季度的天数