首页 > 解决方案 > 在关闭应用程序时获取“包裹:无法编组价值”

问题描述

我有一个片段,在单击“下一步”时,我序列化对象“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);
    }
}

标签: android

解决方案


我从可序列化切换到可打包。这个答案在这里帮助我解决了这个问题。

模型现在看起来像这样:

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);

推荐阅读