当活动之间传递时,Android Bundle文件损坏了?

3
我将尝试在两个活动之间传递一个包含可 Parcelable 对象和字符串值的 ArrayList。以下是将数据添加到 Intent 并通过它传递的代码:
Intent intent = new Intent(this, DisplayLotListActivity.class);
Bundle dataBundle = new Bundle();
dataBundle.putParcelableArrayList(DisplayLotListActivity.EXTRA_LOT_ARRAY, lotList);
dataBundle.putString(EXTRA_LOT_NUMBER, lotNumber);
intent.putExtra(DisplayLotListActivity.EXTRA_DATA, dataBundle);
startActivity(intent);

这是我用来从目标活动中获取意图数据的代码:
Intent intent = getIntent();
Bundle dataBundle = intent.getBundleExtra(EXTRA_DATA);
lotList = dataBundle.getParcelableArrayList(EXTRA_LOT_ARRAY);
lotNumber = dataBundle.getString(LotInquiryActivity.EXTRA_LOT_NUMBER);

当我检查调试器时,活动被调用之前数据结构看起来是正确的,但是当我进入目标活动时,数据结构已经被破坏了。具体来说,ArrayList有3个元素,大小仍为3,但第二个元素为null。然后在bundle中有一个额外的对象,其中包含缺失的元素对象和一个null键。我有调试器之前和之后的图片,但由于反垃圾邮件规则,无法将其发布在帖子中。
之前:http://i.stack.imgur.com/vDipq.png 之后:http://i.stack.imgur.com/JqbF7.png 我是否漏掉了什么?无论是使用Bundle还是直接将ArrayList添加到意图中,都会出现此问题。这在运行Android 4.0.3的三星Tab 2上发生。在4.0模拟器上也会发生这种情况。
[编辑] 这是使用的Parcelable对象(我只是留下了底部的getter和setter方法)。
public class Lot implements Parcelable{

private String lotn;

private String dsc1;
private String dsc2;
private String litm;
private long itm;
private String locn;
private String mcu;
private String uom1;
private String uom2;
private BigDecimal pqav;
private BigDecimal pqoh;
private BigDecimal sqoh;
private long vend;
private String rlot;
private String ldsc;
private String lots;
private String lot1;
private String lot2;
private String lot3;
private String lotsdsc;
private XMLGregorianCalendar mmej;
private XMLGregorianCalendar ohdj;

public Lot(){

}

public Lot(Parcel source){
    lotn = source.readString();
    dsc1 = source.readString();
    dsc2 = source.readString();
    litm = source.readString();
    locn = source.readString();
    mcu = source.readString();
    uom1 = source.readString();
    uom2 = source.readString();
    itm = source.readLong();
    pqav = new BigDecimal(source.readString());
    pqoh = new BigDecimal(source.readString());
    sqoh = new BigDecimal(source.readString());
    vend = source.readLong();
    rlot = source.readString();
    ldsc = source.readString();
    lots = source.readString();
    lot1 = source.readString();
    lot2 = source.readString();
    lot3 = source.readString();
    lotsdsc = source.readString();
    try{
        mmej = DatatypeFactory.newInstance().newXMLGregorianCalendar(source.readString());
    }catch (Exception exc){
        mmej = null;
    }
    try{
        ohdj = DatatypeFactory.newInstance().newXMLGregorianCalendar(source.readString());
    }catch (Exception exc){
        ohdj = null;
    }
}

public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(lotn);
    dest.writeString(dsc1);
    dest.writeString(dsc2);
    dest.writeString(litm);
    dest.writeString(locn);
    dest.writeString(mcu);
    dest.writeString(uom1);
    dest.writeString(uom2);
    dest.writeLong(itm);
    if(pqav != null){
        dest.writeString(pqav.toPlainString());
    } else {
        dest.writeString("0");
    }
    if(pqoh != null){
        dest.writeString(pqoh.toPlainString());
    } else {
        dest.writeString("0");
    }
    if(sqoh != null){
        dest.writeString(sqoh.toPlainString());
    } else {
        dest.writeString("0");
    }
    dest.writeLong(vend);
    dest.writeString(rlot);
    dest.writeString(ldsc);
    dest.writeString(lots);
    dest.writeString(lot1);
    dest.writeString(lot2);
    dest.writeString(lot3);
    dest.writeString(lotsdsc);
    if(mmej != null){
        dest.writeString(mmej.toXMLFormat());
    } else {
        dest.writeString("");
    }
    if(ohdj != null){
        dest.writeString(ohdj.toXMLFormat());
    } else {
        dest.writeString("");
    }
}

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

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

1
如果您将自定义的Parcelable类替换为Android API类(如Rect),这种情况是否仍会发生? - Todd Sjolander
似乎不是这样,我刚刚使用Rect尝试了相同的代码,并且按预期工作。我的自定义Parcelable对象包含字符串、长整型、BigDecimal和XMLGregorianCalendar对象。我在writeToParcel代码中将最后两种类型表示为字符串。 - Moth
你的问题可能出在那段代码上。你能把它发出来吗? - Todd Sjolander
感谢您的编辑。我唯一注意到的问题是缺少describeContents()方法。我不确定这会产生什么影响,如果添加它没有帮助,我认为我会开始注释一些数据成员以查看出错的位置。由于您可以在调试器中看到它在Bundle内部为空,所以您知道问题存在于writeToParcel()中(这并不意味着您的构造函数中没有问题!) - Todd Sjolander
1个回答

3

好的,针对那些回到这个问题的人,我发现了两个问题,我认为这两个问题结合在一起导致了这种行为。所有问题都与我使用的 Parcelable 对象有关,所以感谢 Todd 至少指引了我方向。

首先,我在 Parcelable 对象的构造函数中错过了一个 readString(),所以基本上我写出了 n 个元素并读入了 n - 1 个元素。第二个问题是,Android 没有实现 javax.xml.datatype 库,这意味着 XMLGregorianCalendar 不可用。由于我不需要客户端(它与一个使用它的 Java Web 应用程序进行通信)上此类的功能,因此我只转换为一个简单的 java.util.Date 对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接