2014-09-05 81 views
0

我希望我可以立即給這個問題一個賞金,我已經被這個問題阻止了一天。getParcelableArrayListExtra返回arraylist與布爾false作爲第二個對象

的情況有點複雜:

我試圖從一個活動發送一個ArrayList到另一個使用意向的羣衆演員。如果我把它在意圖後直接調試代碼,這似乎是確定:

in intent

如果你看一下手錶,你可以看到,意圖是正確填寫。

如果ArrayList只包含1個對象,則一切都會消失,但如果它包含多於1個對象則不會生效。然後我得到以下錯誤:

Caused by: java.lang.RuntimeException: Parcel [email protected]: 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]; 
    } 
}; 

}

class 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]; 
     } 
    }; 
} 

和載波(實現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]; 
     } 
    }; 
} 

回答

0

你有多少空覈查處理List<?> S和Parcelable就是爲了要避免空引用。我建議你忽略這個,如果它是空的話,把它放在Parcel

+0

即使沒有我得到相同的結果,也是在這個錯誤之後創建的所有東西 – 2014-09-05 12:22:25

1

OrderLineLocation.writeToParcel,OrderLineID只有在Location != null才被寫入。 但是,當在OrderLineLocation(Parcel in)中讀取時,總是有一個readInt()調用OrderLineID,沒有條件,因此可能導致讀取和寫入序列之間的偏移不匹配。

+0

你是對的,我也只是發現了這個錯誤。現在我得到一個BadParcelableException:ClassNotFoundException當解組「nl.raakict.android.spc.Model.OrderLineLocation。(OrderLineLocation.java:137)」,這是「this.Location = in.readParcelable(nl.raakict.android.spc .Model.LocationBase.class.getClassLoader());」有任何想法嗎? – 2014-09-05 12:44:52

+0

雖然我對此有所懷疑,但是 - 您是否試圖將null作爲參數傳遞給'readParcelable()'調用?這應該使它回退到默認的類加載器,這可能是你想要的。 – sfThomas 2014-09-05 12:51:08

+0

嗯,我確實需要正確的ClassLoader。我把它改爲: 包裹在 if(in.readByte()== 1) this。Location = in.readParcelable(Carrier.class.getClassLoader()); else this.Location = in.readParcelable(Location.class.getClassLoader()); writeToParcel: dest.writeByte((byte)(this.Location instanceof Carrier?1:0)); dest.writeParcelable(this.Location,0); 沒有運氣 – 2014-09-05 12:54:36

相關問題