android - 在关闭应用程序时获取“包裹:无法编组价值”
问题描述
我有一个片段,在单击“下一步”时,我序列化对象“DishItem”的数组列表,并通过 MainActivity 将其传递给后续片段。当我点击设备上的主页按钮并关闭应用程序时,它会崩溃并出现以下错误:
Process: com.edgeshipments.logistics, PID: 21555
java.lang.RuntimeException: Parcel: unable to marshal value com.edgeshipments.logistics.Menu.DishItem@799475b
at android.os.Parcel.writeValue(Parcel.java:1885)
at android.os.Parcel.writeList(Parcel.java:1092)
at android.os.Parcel.writeValue(Parcel.java:1832)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:975)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1044)
at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:167)
at android.os.Parcel.writeTypedObject(Parcel.java:1737)
at android.os.Parcel.writeTypedList(Parcel.java:1616)
at android.os.Parcel.writeTypedList(Parcel.java:1573)
at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:51)
at android.os.Parcel.writeParcelable(Parcel.java:1904)
at android.os.Parcel.writeValue(Parcel.java:1810)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:975)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4389)
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:145)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
这是我的模型课:
public class DishItem implements Comparable {
private String menuItemDescription, menuItemName;
private double deliveryPrice, pickupPrice;
private int levelCode;
public DishItem() {
}
public DishItem(String menuItemDescription, String menuItemName, int levelCode, double deliveryPrice, double pickupPrice) {
this.menuItemDescription = menuItemDescription;
this.menuItemName = menuItemName;
this.levelCode = levelCode;
this.deliveryPrice = deliveryPrice;
this.pickupPrice = pickupPrice;
}
public String getMenuItemDescription() {
return menuItemDescription;
}
public String getMenuItemName() {
return menuItemName;
}
public int getLevelCode() {
return levelCode;
}
public double getDeliveryPrice() {
return deliveryPrice;
}
public double getPickupPrice() {
return pickupPrice;
}
@Override
public int compareTo(Object o) {
int compareLevel = ((DishItem)o).getLevelCode();
return this.levelCode - compareLevel;
}
}
这就是我如何将对象的数组列表添加到第一个片段中的包中:
bundle.putSerializable("restaurantMenu", dishItems);
这就是我打开包以检索对象数组的方式:
dishItemArrayList = (ArrayList<DishItem>) bundle.getSerializable(restaurantMenu);
奇怪的是,我可以用任何其他随机片段替换第二个片段,我遇到了同样的问题,但是当我从第二个片段关闭应用程序时,应用程序只会崩溃。很明显,当我通过 MainActivity 进行通信时,就会发生这种情况。这就是我在实现片段之间的接口时所做的一切:
@Override
public void onRestaurantMap(Bundle bundle) {
boolean direction = bundle.getBoolean("direction");
if (direction) {
bundle.clear();
bundle = new Bundle();
MenuCardFragment fragment = new MenuCardFragment();
openFragment(bundle, fragment, true);
} else {
CreateFragment fragment = new CreateFragment();
openFragment(bundle, fragment, false);
}
}
解决方案
我从可序列化切换到可打包。这个答案在这里帮助我解决了这个问题。
模型现在看起来像这样:
public class DishItem implements Comparable, Parcelable {
private String menuItemDescription, menuItemName;
private double deliveryPrice, pickupPrice;
private int levelCode;
public DishItem() {
}
public DishItem(String menuItemDescription, String menuItemName, int levelCode, double deliveryPrice, double pickupPrice) {
this.menuItemDescription = menuItemDescription;
this.menuItemName = menuItemName;
this.levelCode = levelCode;
this.deliveryPrice = deliveryPrice;
this.pickupPrice = pickupPrice;
}
protected DishItem(Parcel in) {
menuItemDescription = in.readString();
menuItemName = in.readString();
deliveryPrice = in.readDouble();
pickupPrice = in.readDouble();
levelCode = in.readInt();
}
public static final Creator<DishItem> CREATOR = new Creator<DishItem>() {
@Override
public DishItem createFromParcel(Parcel in) {
return new DishItem(in);
}
@Override
public DishItem[] newArray(int size) {
return new DishItem[size];
}
};
public String getMenuItemDescription() {
return menuItemDescription;
}
public String getMenuItemName() {
return menuItemName;
}
public int getLevelCode() {
return levelCode;
}
public double getDeliveryPrice() {
return deliveryPrice;
}
public double getPickupPrice() {
return pickupPrice;
}
@Override
public int compareTo(Object o) {
int compareLevel = ((DishItem)o).getLevelCode();
return this.levelCode - compareLevel;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(menuItemDescription);
parcel.writeString(menuItemName);
parcel.writeDouble(deliveryPrice);
parcel.writeDouble(pickupPrice);
parcel.writeInt(levelCode);
}
}
添加到捆绑包:
bundle.putParcelableArrayList(RESTAURANT_MENU, dishItems);
从捆绑中提取:
dishItemArrayList = bundle.getParcelableArrayList(RESTAURANT_MENU);
推荐阅读
- css - Vue.js 动态值自动换行
- c# - 无法在 Visual Studio 的 Visual Basic.net 中创建 Windows 窗体应用程序
- unity3d - Unity 2019 - 着色器图 - 如何在 UIImage 中重新创建填充功能
- objective-c - 尝试将 Object-C 转换为 Applescriptobjc 以用于 instagram 帖子查找器
- java - 写入 txt 文件,空指针异常
- python - 如何使用 Apache2、mod_wsgi 和 Anaconda 运行 Django 应用程序?
- c - 如果使用两个结构,如何存储二叉搜索树的根?
- spring-boot - 如何在春季靴子中暴露骆驼mbean?
- java - 我无法按照 udacity 的教程生成 SHA1 密钥
- javascript - 如何通过 Javascript 从 JSON 输入创建 HTML?