0

我希望我能马上给这个问题一个赏金,我已经被这个问题拖了一天多。

情况有点复杂:

我正在尝试使用意图的附加功能将 ArrayList 从一个活动发送到另一个活动。如果我在将代码放入意图后直接调试代码,它似乎没问题:

有意

如果您查看手表,您会发现意图已正确填充。

如果 ArrayList 仅包含 1 个对象,则一切正常,但如果它包含 1 个以上的对象,则不会。然后我收到以下错误:

   Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@2133e0d8: Unmarshalling unknown type code 6619168 at offset 392
            at android.os.Parcel.readValue(Parcel.java:2032)
            at android.os.Parcel.readListInternal(Parcel.java:2235)
            at android.os.Parcel.readArrayList(Parcel.java:1655)
            at android.os.Parcel.readValue(Parcel.java:1986)
            at android.os.Parcel.readMapInternal(Parcel.java:2226)
            at android.os.Bundle.unparcel(Bundle.java:223)
            at android.os.Bundle.getParcelableArrayList(Bundle.java:1217)
            at android.content.Intent.getParcelableArrayListExtra(Intent.java:4798)
            at nl.raakict.android.spc.SearchMapActivity.onCreate(SearchMapActivity.java:85)
            at android.app.Activity.performCreate(Activity.java:5267)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2295)
            at android.app.ActivityThread.access$700(ActivityThread.java:150)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:176)
            at android.app.ActivityThread.main(ActivityThread.java:5279)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
            at dalvik.system.NativeStart.main(Native Method)

我添加了对象(和兄弟对象)的代码。请注意,这里有一个吸引人的地方,我还有一个实现 Parcellable 的抽象类:

订单线类:

package nl.raakict.android.spc.Model;

import android.os.Parcel;
import android.os.Parcelable;
import nl.raakict.android.spc.Interface.RenewOrderLinesListener;
import nl.raakict.android.spc.Interface.onApiCompleteListener;

import java.util.ArrayList;
import java.util.List;

public class OrderLine extends BaseModel implements onApiCompleteListener, Parcelable {

    private int ID;
    private int OrderID;
    private String Order_Number;
    private String PartName;
    private String Materiaal;
    private double Thickness;
    private double XSize;
    private double YSize;
    private int Amount;
    private String ImagePath;
    private String PositionNumber;
    private double Weight;
    private String Remark;
    private String BonNumber;
    private int ParentOrderLineID;
    private String ParentAssemblyName;
    private String Barcode;
    private ArrayList<OrderLineOperation> OrderLineOperations;
    private ArrayList<OrderLineLocation> ActiveOrderLineLocations;
    private String StatusColor;
    private boolean Completed;
    private long LocationID;
    private int CustomerID;
    private String CustomerName;
    private OrderLineOperation CurrentOperation;
    private boolean IsTransportReady;
    private String PlanningLocation;
    private transient RenewOrderLinesListener apiCompleteListener;

    public OrderLine(){
        ActiveOrderLineLocations = new ArrayList<OrderLineLocation>();
    }


 // Getters, setters, derived methods of onApiCompleteListener



    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(getID());
        dest.writeString(getPartName());
        dest.writeInt(OrderID);
        dest.writeString(Order_Number);
        if(ActiveOrderLineLocations == null || ActiveOrderLineLocations.isEmpty())
            dest.writeByte((byte) 0);
        else {
            dest.writeByte((byte) 1);
            dest.writeTypedList(ActiveOrderLineLocations);
        }
    }

    public OrderLine(Parcel in) {
        this();
        ID = in.readInt();
        PartName = in.readString();
        OrderID = in.readInt();
        Order_Number = in.readString();
        if(in.readByte() == (byte)1)
            in.readTypedList(ActiveOrderLineLocations, OrderLineLocation.CREATOR);
    }

    /**
     * * This field is needed for Android to be able to * create new objects, individually or as arrays. * * This also means that you can use use the default * constructor to create the object and use another * method to hyrdate it as necessary. * * I just find it easier to use the constructor. * It makes sense for the way my brain thinks ;-) *
     */
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public OrderLine createFromParcel(Parcel in) {
            return new OrderLine(in);
        }

        public OrderLine[] newArray(int size) {
            return new OrderLine[size];
        }
    };

    public ArrayList<OrderLineLocation> getActiveOrderLineLocations() {
        return ActiveOrderLineLocations;
    }

    public void setActiveOrderLineLocations(ArrayList<OrderLineLocation> activeOrderLineLocations) {
        ActiveOrderLineLocations = activeOrderLineLocations;
    }
}

类 OrderLineLocation:

package nl.raakict.android.spc.Model;

import android.os.Parcel;
import android.os.Parcelable;

public class OrderLineLocation extends BaseModel implements Parcelable {

private int ID;
private OrderLine OrderLine;
private int OrderLineID;
private int CurrentAmount;
private LocationBase Location;
private String DateChanged;
private long UserID;
private boolean Archive;
private boolean IsOnStockLocation;
private String SupplierID;
private long LocationID;


@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeInt(this.ID);
    if (this.OrderLine != null) {
        dest.writeByte((byte) 1);
        dest.writeParcelable(this.OrderLine, 0);
    } else
        dest.writeByte((byte) 0);
    if (this.Location != null) {
        dest.writeByte((byte) 1);
        dest.writeParcelable(this.Location, 0);
    } else
        dest.writeByte((byte) 0);
    if (this.Location != null)
        dest.writeInt(this.OrderLineID);
    dest.writeInt(this.CurrentAmount);
    dest.writeString(this.DateChanged);
    dest.writeLong(this.UserID);
    dest.writeByte(Archive ? (byte) 1 : (byte) 0);
    dest.writeByte(IsOnStockLocation ? (byte) 1 : (byte) 0);
    dest.writeString(this.SupplierID);
}

public OrderLineLocation() {
}

private OrderLineLocation(Parcel in) {
    this.ID = in.readInt();
    if (in.readByte() == (byte) 1)
        this.OrderLine = in.readParcelable(nl.raakict.android.spc.Model.OrderLine.class.getClassLoader());
    if (in.readByte() == (byte) 1)
        this.Location = in.readParcelable(nl.raakict.android.spc.Model.LocationBase.class.getClassLoader());
    this.OrderLineID = in.readInt();
    this.CurrentAmount = in.readInt();
    this.DateChanged = in.readString();
    this.UserID = in.readLong();
    this.Archive = in.readByte() != (byte) 0;
    this.IsOnStockLocation = in.readByte() != (byte) 0;
    this.SupplierID = in.readString();
}

public static final Parcelable.Creator<OrderLineLocation> CREATOR = new Parcelable.Creator<OrderLineLocation>() {
    public OrderLineLocation createFromParcel(Parcel source) {
        return new OrderLineLocation(source);
    }

    public OrderLineLocation[] newArray(int size) {
        return new OrderLineLocation[size];
    }
};

}

类 LocationBase (抽象类):

package nl.raakict.android.spc.Model;

import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;

public abstract class LocationBase extends BaseModel implements Parcelable {

    protected String __type;
    protected long Id;
    protected String Name;
    protected String Barcode;
    protected String Remark;
    protected int Discriminator;
    protected int AmountOfSegments;
    protected ArrayList<Carrier> Carriers;
    protected ArrayList<OrderLineLocation> OrderLineLocations;
    protected ArrayList<Order_Header> Orders;
    protected LocationBase Location;
    protected ArrayList<OrderLineLocation> ActiveLocations;



    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.__type);
        dest.writeLong(this.Id);
        dest.writeString(this.Name);
        dest.writeString(this.Barcode);
        dest.writeString(this.Remark);
        dest.writeInt(this.Discriminator);
        dest.writeInt(this.AmountOfSegments);
        if(this.ActiveLocations == null || this.ActiveLocations.isEmpty())
            dest.writeByte((byte) 0);
        else {
            dest.writeByte((byte) 1);
            dest.writeTypedList(this.ActiveLocations);
        }
        if(this.Orders == null || this.Orders.isEmpty())
            dest.writeByte((byte) 0);
        else {
            dest.writeByte((byte) 1);
            dest.writeTypedList(this.Orders);
        }
    }

    public LocationBase() {
    }


    public static final Parcelable.Creator<LocationBase> CREATOR = new Parcelable.Creator<LocationBase>() {
        public LocationBase createFromParcel(Parcel source) {
            Byte b = source.readByte();
            if(b == 0)
                return nl.raakict.android.spc.Model.Carrier.CREATOR.createFromParcel(source);
            else
                return nl.raakict.android.spc.Model.Location.CREATOR.createFromParcel(source);
        }

        public LocationBase[] newArray(int size) {
            return new LocationBase[size];
        }
    };
}

和 Carrier(实现 LocationBase 抽象类)

package nl.raakict.android.spc.Model;

import android.os.Parcel;
import android.os.Parcelable;

public class Carrier extends LocationBase {

    private int LocationID;
    private int CarrierTypeID;
    private boolean CanBePlacedOnCarrier;
    private boolean CanBeCarrierLocation;
    protected int StartSegment;
    private String CarrierTypeName;
    private int NumberOfEdges;
    private transient int Indentation;


    public Carrier() {
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeByte((byte) 0);
        super.writeToParcel(dest, flags);
        if (this.Location != null) {
            dest.writeByte((byte) 1);
            dest.writeParcelable(this.Location, 0);
        } else
            dest.writeByte((byte) 0);
    }

    protected Carrier(Parcel in) {
        this.__type = in.readString();
        this.Id = in.readLong();
        this.Name = in.readString();
        this.Barcode = in.readString();
        this.Remark = in.readString();
        this.Discriminator = in.readInt();
        this.AmountOfSegments = in.readInt();
        if(in.readByte() == (byte)1)
            in.readTypedList(ActiveLocations, OrderLineLocation.CREATOR);
        if(in.readByte() == (byte)1)
            in.readTypedList(Orders, Order_Header.CREATOR);
        if (in.readByte() == (byte) 1)
            this.Location = in.readParcelable(nl.raakict.android.spc.Model.LocationBase.class.getClassLoader());
    }

    public static final Parcelable.Creator<LocationBase> CREATOR = new Parcelable.Creator<LocationBase>() {
        public Carrier createFromParcel(Parcel in) {
            return new Carrier(in);
        }

        public Carrier[] newArray(int size) {
            return new Carrier[size];
        }
    };

}

最后上课地点

package nl.raakict.android.spc.Model;

import android.os.Parcel;
import android.os.Parcelable;

public class Location extends LocationBase  {

    protected int LocationGroupID;
    protected int PositionZ;

    public Location() {
    }

    protected Location(Parcel in) {
        this.__type = in.readString();
        this.Id = in.readLong();
        this.Name = in.readString();
        this.Barcode = in.readString();
        this.Remark = in.readString();
        this.Discriminator = in.readInt();
        this.AmountOfSegments = in.readInt();
        if(in.readByte() == (byte)1)
            in.readTypedList(ActiveLocations, OrderLineLocation.CREATOR);
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeByte((byte) 1);
        super.writeToParcel(dest, flags);
    }

    public static final Parcelable.Creator<LocationBase> CREATOR = new Parcelable.Creator<LocationBase>() {
        public Location createFromParcel(Parcel source) {
            return new Location(source);
        }

        public Location[] newArray(int size) {
            return new Location[size];
        }
    };
}
4

2 回答 2

1

OrderLineLocation.writeToParcel中,OrderLineID仅在 时写入Location != null。但是,在读入 时OrderLineLocation(Parcel in),总是会无条件地readInt()调用,因此可能会导致读取和写入序列之间的偏移不匹配。OrderLineID

于 2014-09-05T12:35:18.580 回答
0

为了避免空引用,您必须进行大量空验证来处理List<?>s 和s。Parcelable我建议你忽略这个,不管它是否为空,把它放在Parcel.

于 2014-09-05T12:21:03.917 回答