Android:如何使用自定义类型为ArrayList <t>正确实现Parcelable?

时间:2015-07-14 11:37:01

标签: android arraylist parcelable

编辑回复qbix的回答

我有一个保存数据的类,用于在活动之间传递数据。它有几个字段,主要是String,但还有两个字段,它们是ArrayList类型,另一个是ArrayList

当我尝试从意图中获取数据时,我得到一个例外: java.lang.RuntimeException: Parcel android.os.Parcel@53614d6c: Unmarshalling unknown type code 7471184 at offset 156

我认为这个问题存在于一个没有正确处理的ArrayList的地方。

如何使用自定义类型正确实现Parcelable for Array?

以下是我的课程:

public class OpeningPeriod implements java.io.Serializable{
    private int openDay;
    private String openTime;
    private int closeDay;
    private String closeTime;

public OpeningPeriod() {
}

public OpeningPeriod(int closeDay, String closeTime, int openDay, String openTime) {
    this.closeDay = closeDay;
        this.closeTime = closeTime;
        this.openDay = openDay;
        this.openTime = openTime;
    }
    // here come the getters and setters....
}

我编辑的Parcelable仍在崩溃:

public class AddresseDetails implements Parcelable {
private String placeId;
private String strasse;
private String hausNummer;
private String ort;
private String plz;
private String phone;
private String web;
private ArrayList<String> weekDayText;
private String name;

public AddresseDetails() {
}

public AddresseDetails(Parcel source) {
    readFromParcel(source);
}

public AddresseDetails(String hausNummer,
                       String name,
                       String ort,
                       ArrayList<OpeningPeriod> periods,
                       String phone,
                       String placeId,
                       String plz,
                       String strasse,
                       String web,
                       ArrayList<String> weekDayText) {
    this.hausNummer = hausNummer;
    this.name = name;
    this.ort = ort;
    this.periods = periods;
    this.phone = phone;
    this.placeId = placeId;
    this.plz = plz;
    this.strasse = strasse;
    this.web = web;
    this.weekDayText = weekDayText;
}

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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeString(placeId);
    dest.writeString(strasse);
    dest.writeString(hausNummer);
    dest.writeString(ort);
    dest.writeString(plz);
    dest.writeString(phone);
    dest.writeString(web);

    dest.writeStringList(weekDayText);

}

public void readFromParcel(Parcel source){
    name = source.readString();
    placeId = source.readString();
    strasse = source.readString();
    hausNummer = source.readString();
    ort = source.readString();
    plz = source.readString();
    phone = source.readString();
    web = source.readString();

    source.readStringList(weekDayText);

}

public static final Parcelable.Creator<AddresseDetails> CREATOR = new Parcelable.Creator<AddresseDetails>() {

    @Override
    public AddresseDetails createFromParcel(Parcel source) {
        return new AddresseDetails(source);
    }

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

}

它在source.readStringList(weekDayText);

中崩溃了

有什么建议吗?

解决方案:

public class AddresseDetails implements Parcelable {
private String placeId;
private String strasse;
private String hausNummer;
private String ort;
private String plz;
private String phone;
private String web;
private ArrayList<String> weekDayText;
private ArrayList<OpeningPeriod> periods;
private String name;

public AddresseDetails() {
}

public AddresseDetails(Parcel source) {
    readFromParcel(source);
}

public AddresseDetails(String hausNummer,
                       String name,
                       String ort,
                       ArrayList<OpeningPeriod> periods,
                       String phone,
                       String placeId,
                       String plz,
                       String strasse,
                       String web,
                       ArrayList<String> weekDayText) {
    this.hausNummer = hausNummer;
    this.name = name;
    this.ort = ort;
    this.periods = periods;
    this.phone = phone;
    this.placeId = placeId;
    this.plz = plz;
    this.strasse = strasse;
    this.web = web;
    this.weekDayText = weekDayText;
}

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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeString(placeId);
    dest.writeString(strasse);
    dest.writeString(hausNummer);
    dest.writeString(ort);
    dest.writeString(plz);
    dest.writeString(phone);
    dest.writeString(web);

    dest.writeStringList(weekDayText);
    dest.writeTypedList(periods);

}

public void readFromParcel(Parcel source){
    name = source.readString();
    placeId = source.readString();
    strasse = source.readString();
    hausNummer = source.readString();
    ort = source.readString();
    plz = source.readString();
    phone = source.readString();
    web = source.readString();

    weekDayText = source.createStringArrayList();
    periods = source.createTypedArrayList(OpeningPeriod.CREATOR);

}

public static final Parcelable.Creator<AddresseDetails> CREATOR = new Parcelable.Creator<AddresseDetails>() {

    @Override
    public AddresseDetails createFromParcel(Parcel source) {
        return new AddresseDetails(source);
    }

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

    public static final Parcelable.Creator<OpeningPeriod> CREATOR = new Parcelable.Creator<OpeningPeriod>() {

    @Override
    public OpeningPeriod createFromParcel(Parcel source) {
        return new OpeningPeriod(source);
    }

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

2 个答案:

答案 0 :(得分:0)

尝试使用:

periods = source.readArrayList(OpeningPeriod.class.getClassLoader());

答案 1 :(得分:0)

将带有Parcel参数的构造函数替换为:

public AddresseDetails(Parcel source) {
    readFromParcel(source);
}

您现有的构造函数不是按照它们编写的顺序从包中读取对象成员。

这是我的测试用例。我会做更多的实验。也许存储在一个包中并不会调用所有的包裹操作:

OpeningPeriod op = new OpeningPeriod(111, "close", 222, "open");
ArrayList<OpeningPeriod> periods = new ArrayList<>(3);
periods.add(op);

ArrayList<String> weekDays = new ArrayList<>(3);
weekDays.add("aaa");
weekDays.add("bbb");
weekDays.add("ccc");

AddresseDetails ad = new AddresseDetails("number", "name", "ort", periods, "phone",
        "place", "plz", "strasse", "web", weekDays);

Bundle b = new Bundle();
b.putParcelable("test", ad);

AddresseDetails ad2 = b.getParcelable("test");

Log.i("Test", "Phone=" + ad.phone + " " + ad2.phone);
Log.i("Test", "WeekDay1=" + ad.weekDayText.get(1) + " " + ad2.weekDayText.get(1));