4

我遇到了一些Parcelable自定义类的问题,我正在使用这个自定义类来安装Android应用程序,而我已经设法以非常奇怪的方式解决这个问题。Android Parcelable订单

我只在几个特定的​​情况下从一个parcelable读取时发生了崩溃(这导致我认为我的实现并非完全错误)。

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.worldcraze.worldcraze/com.worldcraze.worldcraze.AdActivity}: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: Surface Book 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Caused by: android.os.BadParcelableException: ClassNotFoundException when  unmarshalling: Surface Book 
at android.os.Parcel.readParcelableCreator(Parcel.java:2432) 
at android.os.Parcel.readParcelable(Parcel.java:2358) 
at com.worldcraze.worldcraze.API.Model.TransportOffer.<init>  (TransportOffer.java:33) 
at  com.worldcraze.worldcraze.API.Model.TransportOffer$1.createFromParcel(TransportO ffer.java:43) 
    at  com.worldcraze.worldcraze.API.Model.TransportOffer$1.createFromParcel(TransportO ffer.java:40) 
at android.os.Parcel.createTypedArray(Parcel.java:2167) 
at com.worldcraze.worldcraze.API.Model.Ad.<init>(Ad.java:42) 
at com.worldcraze.worldcraze.API.Model.Ad$1.createFromParcel(Ad.java:52) 
at com.worldcraze.worldcraze.API.Model.Ad$1.createFromParcel(Ad.java:49) 
at android.os.Parcel.readParcelable(Parcel.java:2367) 
at android.os.Parcel.readValue(Parcel.java:2264) 
at android.os.Parcel.readArrayMapInternal(Parcel.java:2614) 
at android.os.BaseBundle.unparcel(BaseBundle.java:221) 
at android.os.Bundle.getParcelable(Bundle.java:786) 
at android.content.Intent.getParcelableExtra(Intent.java:5377) 
at com.worldcraze.worldcraze.AdActivity.onCreate(AdActivity.java:57) 
at android.app.Activity.performCreate(Activity.java:6251) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) 
... 9 more 

这是我原来实行的崩溃是在(Ad.java)存在的模型

public class Ad implements Parcelable { 

public String    author; 
public String    transporter; 
public Image    cover_urls; 
public String    details; 
public String    id; 
public int     item_size; 
public String    object_name; 
public Money    tips; 
public Money    price; 
public Location   where_to_buy; 
public String    resource_uri; 
public Location   where_to_deliver; 
public Permissions   permissions; 
public TransportOffer[] transport_offers; 
public float    fees_lemonway_CB; 
public String    validation_code; 
public Date    creation_dtime; 
public String    accepted_transport_offer_id; 

protected Ad(Parcel in) { 
    author   = in.readString(); 
    transporter  = in.readString(); 
    details   = in.readString(); 
    id    = in.readString(); 
    item_size  = in.readInt(); 
    object_name  = in.readString(); 
    resource_uri  = in.readString(); 
    cover_urls  = in.readParcelable(Image.class.getClassLoader()); 
    tips    = in.readParcelable(Money.class.getClassLoader()); 
    price   = in.readParcelable(Money.class.getClassLoader()); 
    permissions  = in.readParcelable(Permissions.class.getClassLoader()); 
    transport_offers = in.createTypedArray(TransportOffer.CREATOR); 
    where_to_buy  = in.readParcelable(Location.class.getClassLoader()); 
    where_to_deliver = in.readParcelable(Location.class.getClassLoader()); 
    fees_lemonway_CB = in.readFloat(); 
    validation_code = in.readString(); 
    creation_dtime = (Date) in.readSerializable(); 
    accepted_transport_offer_id = in.readString(); 
} 

public static final Creator<Ad> CREATOR = new Creator<Ad>() { 
    @Override 
    public Ad createFromParcel(Parcel in) { 
     return new Ad(in); 
    } 

    @Override 
    public Ad[] newArray(int size) { 
     return new Ad[size]; 
    } 
}; 

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

@Override 
public void writeToParcel(Parcel dest, int flags) { 
    dest.writeString(author); 
    dest.writeString(transporter); 
    dest.writeString(details); 
    dest.writeString(id); 
    dest.writeInt(item_size); 
    dest.writeString(object_name); 
    dest.writeString(resource_uri); 
    dest.writeParcelable(cover_urls, flags); 
    dest.writeParcelable(tips, flags); 
    dest.writeParcelable(price, flags); 
    dest.writeParcelable(permissions, flags); 
    dest.writeTypedArray(transport_offers, flags); 
    dest.writeParcelable(where_to_buy, flags); 
    dest.writeParcelable(where_to_deliver, flags); 
    dest.writeFloat(fees_lemonway_CB); 
    dest.writeString(validation_code); 
    dest.writeSerializable(creation_dtime); 
    dest.writeString(accepted_transport_offer_id); 
} 

}的

我设法通过改变读取为了解决该问题/写一些Parcelable属性。 我现在正在读/写where_to_buy和where_to_deliver在cover_urls之前似乎已经解决了问题。

where_to_buy  = in.readParcelable(Location.class.getClassLoader()); 
    where_to_deliver = in.readParcelable(Location.class.getClassLoader()); 
    cover_urls  = in.readParcelable(Image.class.getClassLoader()); 
    tips    = in.readParcelable(Money.class.getClassLoader()); 
    price   = in.readParcelable(Money.class.getClassLoader()); 
    permissions  = in.readParcelable(Permissions.class.getClassLoader()); 
    transport_offers = in.createTypedArray(TransportOffer.CREATOR); 

(在writeToParcel中的顺序是相同的,我只是通过不粘贴它在这里保存几行)。

这个奇怪的修复工作就像一个魅力,我不知道为什么。

有没有人遇到类似的东西或知道为什么包装/拆包的顺序会影响结果?

干杯!

回答

4

这不是一个不正常的行为。如果你明白它在内部是如何工作的,你就会明白为什么你会遇到异常。

序列化基本上是按字节顺序写入的。因此,您按照某种顺序(例如4-16-1-2)写入了一些可变长度的字节,然后您从Parcel读取字节。

在从Parcel读取数据时,尝试读取例如16字节,但实际上已经写了4个字节,这就是为什么会发生崩溃。

阅读的顺序应该与写作的顺序一致,否则当你尝试阅读时,最终会出现这种情况。 16个字节,但实际上你的变量是4个字节。