Android: How do I correctly implement Parcelable for Objects with ArrayList<T> with custom types? -
edited refelect qbix's answer
i have class holds data , used passing around data between activities. has couple of fields, string, 2 more fields of type arraylist , arraylist
when try data intent back, getting exception: java.lang.runtimeexception: parcel android.os.parcel@53614d6c: unmarshalling unknown type code 7471184 @ offset 156
i think problem lies somewhere having arraylist not correctly handled.
how correctly implement parcelable arraylist custom types?
here classes:
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 getters , setters.... }
and edited parcelable, still crashes:
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]; } };
}
and crashes in source.readstringlist(weekdaytext);
any suggestions?
solution:
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]; } }; }
replace constructor takes parcel parameter this:
public addressedetails(parcel source) { readfromparcel(source); }
your existing constructor not reading object members parcel in same order written.
this test case. i'll experiment more. maybe storing in bundle doesn't invoke parcel operations:
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));
Comments
Post a Comment