【发布时间】:2014-04-18 13:58:59
【问题描述】:
我在体验 2-depth Parcelable 时遇到了一些问题。我有 3 个班级,包括他们自己作为这个架构:
Serie
List<Qcm>
List<Proposition>
他们都在实现来自android.os.Parcelable 的 Parcelable 接口。
当我尝试使用putExtra() 将Serie 对象传递给另一个活动时,就会出现问题,当我从要检索Serie 对象的活动中使用getParcelable() 时,会出现java.lang.OutOfMemoryError。
正常的行为应该如下:
- 一个 Serie 包含可变数量的 Qcm (N Qcm)
- 一个 Qcm 包含 5 个命题
事实是,当我记录 createFromParcel() 调用时,我看到 Proposition 中的 createFromParcel() 在第一次循环迭代中被调用了 5 次,然后在下一次迭代中永远不会停止调用。
我的堆栈跟踪:
04-18 15:19:19.565 14089-14089/com.examed.maprepaquotidienne D/MPQ.Qcm.createFromParcel﹕ qcm cree
04-18 15:19:19.570 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.570 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.570 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.570 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.575 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.575 14089-14089/com.examed.maprepaquotidienne D/MPQ.Qcm.createFromParcel﹕ qcm cree
04-18 15:19:19.575 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.575 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.580 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.580 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.580 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.580 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.580 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.585 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.585 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.585 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.585 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.590 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.590 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.590 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.590 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.590 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.600 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
04-18 15:19:19.600 14089-14089/com.examed.maprepaquotidienne D/MPQ.Proposition.createFromParcel﹕ proposition cree
Serie.java
package examed.lib.classes;
import android.content.Context;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
import examed.lib.DAO.FrequenceDAO;
import examed.lib.DAO.SerieDAO;
import examed.lib.DAO.UEDAO;
import examed.lib.workers.APIHelper;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Serie implements Parcelable
{
private int id;
private UE uniteEnseignement;
private Frequence frq;
private int type;
private String authorFirstname, authorName, authorAvatar;
private Date datePublication;
private int anneeSerie, nbQcm, order;
private String title, subtitle;
private String beforeText;
private String afterText;
private List<Qcm> listeQcm = new ArrayList<Qcm>();
private float chanceCoeff;
private boolean enCreation;
private boolean publiee;
private Date dateValidationPubliee;
private Date dateFinCreation;
private int maxTime;
private int statut;
public Serie(Parcel in) throws ParseException, NullPointerException
{
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
this.id = in.readInt();
this.uniteEnseignement = in.readParcelable(UE.class.getClassLoader());
this.frq = in.readParcelable(Frequence.class.getClassLoader());
this.type = in.readInt();
this.authorFirstname = in.readString();
this.authorName = in.readString();
this.authorAvatar = in.readString();
this.datePublication = dateFormat.parse(in.readString());
this.anneeSerie = in.readInt();
this.nbQcm = in.readInt();
this.order = in.readInt();
this.title = in.readString();
this.subtitle = in.readString();
this.beforeText = in.readString();
this.afterText = in.readString();
in.readTypedList(this.listeQcm, Qcm.CREATOR);
this.chanceCoeff = in.readFloat();
this.enCreation = (in.readInt() > 0);
this.publiee = (in.readInt() > 0);
this.dateValidationPubliee = dateFormat.parse(in.readString());
this.dateFinCreation = dateFormat.parse(in.readString());
this.maxTime = in.readInt();
this.statut = in.readInt();
}
[...]
// region [PARCELABLE]
@Override
public int describeContents()
{
return 0;
}
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(this.id);
dest.writeParcelable(this.uniteEnseignement, flags);
dest.writeParcelable(this.frq, flags);
dest.writeInt(this.type);
dest.writeString(this.authorFirstname);
dest.writeString(this.authorName);
dest.writeString(this.authorAvatar);
dest.writeString(this.getDatePublication());
dest.writeInt(this.anneeSerie);
dest.writeInt(this.nbQcm);
dest.writeInt(this.order);
dest.writeString(this.title);
dest.writeString(this.subtitle);
dest.writeString(this.beforeText);
dest.writeString(this.afterText);
dest.writeTypedList(this.listeQcm);
dest.writeDouble((double) this.chanceCoeff);
dest.writeInt((this.enCreation) ? 1 : 0);
dest.writeInt((this.publiee) ? 1 : 0);
dest.writeString(this.getDateValidationPubliee());
dest.writeString(this.getDateFinCreation());
dest.writeInt(this.maxTime);
dest.writeInt(this.statut);
}
public static final Parcelable.Creator<Serie> CREATOR = new Parcelable.Creator<Serie>()
{
@Override
public Serie createFromParcel(Parcel source)
{
Serie serie = null;
try {
serie = new Serie(source);
} catch (ParseException e) {
e.printStackTrace();
}
return serie;
}
@Override
public Serie[] newArray(int size)
{
return new Serie[size];
}
};
// endregion
}
Qcm.java
package examed.lib.classes;
import android.os.Parcel;
import android.os.Parcelable;
import examed.lib.workers.APIHelper;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Qcm implements Parcelable
{
private int id;
private String question;
private int typeNotation;
private List<Proposition> propositions = new ArrayList<Proposition>();
private Date dateCreation;
private Date dateUpdate;
private int typeChapitre;
private boolean validee;
private int annee;
private boolean origineAnnale;
private float coeff;
private int duree;
public static String FIELD_QCM_ID = "QCMID";
public static String FIELD_QCM_QUESTION = "Question";
public static String FIELD_QCM_TYPE_NOTATION_ID = "TypeNotationID";
public static String FIELD_QCM_DATE_CREATION = "DateCreation";
public static String FIELD_QCM_DATE_MODIF = "DateUpdate";
public static String FIELD_QCM_TYPE_CHAPITRE = "TypeChapitreID";
public static String FIELD_QCM_VALIDEE = "Validee";
public static String FIELD_QCM_ANNEE = "Annee";
public static String FIELD_QCM_ORIGINE_ANNALE = "OrigineAnnale";
public static String FIELD_QCM_COEFF = "coef";
public static String FIELD_QCM_DUREE = "dureeQCM";
public Qcm(Parcel in) throws ParseException
{
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
this.id = in.readInt();
this.question = in.readString();
this.typeNotation = in.readInt();
in.readTypedList(this.propositions, Proposition.CREATOR);
this.dateCreation = dateFormat.parse(in.readString());
this.dateUpdate = dateFormat.parse(in.readString());
this.typeChapitre = in.readInt();
this.validee = (in.readInt() > 0);
this.annee = in.readInt();
this.origineAnnale = (in.readInt() > 0);
this.coeff = in.readFloat();
this.duree = in.readInt();
}
// region [PARCELABLE]
@Override
public int describeContents()
{
return 0;
}
public void writeToParcel(Parcel dest, int flags)
{
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dest.writeInt(this.id);
dest.writeString(this.question);
dest.writeInt(this.typeNotation);
dest.writeTypedList(this.propositions);
dest.writeString(dateFormat.format(this.dateCreation));
dest.writeString(dateFormat.format(this.dateUpdate));
dest.writeInt(this.typeChapitre);
dest.writeInt((this.validee) ? 1 : 0);
dest.writeInt(this.annee);
dest.writeInt((this.origineAnnale) ? 1 : 0);
dest.writeDouble((double)this.coeff);
dest.writeInt(this.duree);
}
public static final Parcelable.Creator<Qcm> CREATOR = new Parcelable.Creator<Qcm>()
{
@Override
public Qcm createFromParcel(Parcel source)
{
Qcm qcm = null;
APIHelper.log('d', "qcm cree");
try {
qcm = new Qcm(source);
} catch (ParseException e) {
e.printStackTrace();
}
return qcm;
}
@Override
public Qcm[] newArray(int size)
{
return new Qcm[size];
}
};
// endregion
}
Proposition.java
package examed.lib.classes;
import android.os.Parcel;
import android.os.Parcelable;
import examed.lib.workers.APIHelper;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class Proposition implements Parcelable
{
private String content;
private boolean toCheck;
private String correction;
public Proposition(Parcel in) throws ParseException
{
this.content = in.readString();
this.toCheck = (in.readInt() > 0);
this.correction = in.readString();
}
// region [PARCELABLE]
@Override
public int describeContents()
{
return 0;
}
public void writeToParcel(Parcel dest, int flags)
{
dest.writeString(this.content);
dest.writeInt((this.toCheck) ? 1 : 0);
dest.writeString(this.correction);
}
public static final Parcelable.Creator<Proposition> CREATOR = new Parcelable.Creator<Proposition>()
{
@Override
public Proposition createFromParcel(Parcel source)
{
Proposition proposition = null;
try {
proposition = new Proposition(source);
APIHelper.log('d', "proposition cree");
} catch (ParseException e) {
e.printStackTrace();
}
return proposition;
}
@Override
public Proposition[] newArray(int size)
{
return new Proposition[size];
}
};
// endregion
}
我如何在目标 Activity 中执行 getParcelable
Intent intent = getIntent();
if(intent.getExtras() != null)
{
APIHelper.log('d', intent.getExtras().getParcelable("SELECTED_SERIE"));
this.serie = intent.getExtras().getParcelable("SELECTED_SERIE");
APIHelper.log('d', this.serie);
}
如果您还需要其他东西,请告诉我。我已经坚持了几个小时,我真的不明白。 谢谢!
【问题讨论】:
标签: android arraylist out-of-memory infinite-loop parcelable