大家好我正在实现序列化并在android设备内存中保存对象。我有一个用于保存和获取对象的类。问题是我要保存的类具有属性,这些属性是我在我的应用程序中拥有的其他对象的数组列表,当我尝试保存它时,我从应用程序中得到一个未知数。
在两个类的代码下面:
public class CacheTest {
private static final long serialVersionUID = 1L;
public boolean classEnabled;
private File cacheDir;
public CacheTest(Context context) {
// Find the dir to save cached images
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir = new File(android.os.Environment.getExternalStorageDirectory(), "lacartelera");
else
cacheDir = context.getCacheDir();
if (!cacheDir.exists())
cacheDir.mkdirs();
}
public boolean saveObject(StreamData obj) {
final File suspend_f = new File(cacheDir, "streamdata");
FileOutputStream fos = null;
ObjectOutputStream oos = null;
boolean keep = true;
try {
fos = new FileOutputStream(suspend_f);
oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
} catch (Exception e) {
keep = false;
} finally {
try {
if (oos != null)
oos.close();
if (fos != null)
fos.close();
if (keep == false)
suspend_f.delete();
} catch (Exception e) {
}
}
return keep;
}
public void clear() {
File[] files = cacheDir.listFiles();
for (File f : files)
f.delete();
}
public StreamData getObject() {
final File suspend_f = new File(cacheDir, "streamdata");
StreamData streamData = null;
FileInputStream fis = null;
ObjectInputStream is = null;
String val = "";
// boolean keep = true;
try {
fis = new FileInputStream(suspend_f);
is = new ObjectInputStream(fis);
streamData = (StreamData) is.readObject();
} catch (Exception e) {
val = e.getMessage();
} finally {
try {
if (fis != null)
fis.close();
if (is != null)
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return streamData;
}
}
public class StreamData implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int _idStream = 0;
private int _idMensaje = 0;
private String _titulo = "";
private String _mensaje = "";
private String _fechaInicio = "";
private String _fechaFin = "";
private boolean _smartFilter = true;
private boolean _hasChanges = false;
private boolean _notifyUpdates = true;
public ArrayList<Cine> _cines = new ArrayList<Cine>();
public ArrayList<Pelicula> _peliculas = new ArrayList<Pelicula>();
public ArrayList<Pelicula> _estrenos = new ArrayList<Pelicula>();
public ArrayList<Pelicula> _proximamente = new ArrayList<Pelicula>();
public int getIdStream() {
return _idStream;
}
public void setIdStream(int value) {
_idStream = value;
}
public int getIdMensaje() {
return _idMensaje;
}
}
更新:我在logcat debbuger中看到了这个:
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at dalvik.system.BlockGuard.getThreadPolicy(BlockGuard.java:133)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at dalvik.system.BlockGuard$WrappedFileSystem.write(BlockGuard.java:170)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.FileOutputStream.write(FileOutputStream.java:318)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.DataOutputStream.writeByte(DataOutputStream.java:145)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1539)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.util.ArrayList.writeObject(ArrayList.java:651)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.lang.reflect.Method.invokeNative(Native Method)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.lang.reflect.Method.invoke(Method.java:507)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.util.ArrayList.writeObject(ArrayList.java:651)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.lang.reflect.Method.invokeNative(Native Method)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.lang.reflect.Method.invoke(Method.java:507)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
09-04 14:57:16.353: ERROR/AndroidRuntime(959): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
0
其他课程的代码
public class Cine实现了Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public Cine() {
}
public Cine(int idCine) {
_idCine = idCine;
}
public String toString() {
return _cine;
}
public void setDelete(boolean value) {
_delete = value;
if (value)
_programacionesPeliculas.clear();
}
private ArrayList<ProgramacionPelicula> _programacionesPeliculas = new ArrayList<ProgramacionPelicula>();
public ArrayList<ProgramacionPelicula> getProgramacionesPeliculas() {
return _programacionesPeliculas;
}
public void addProgramacionPelicula(ProgramacionPelicula programacion) {
_programacionesPeliculas.add(programacion);
}
}
公共类Pelicula实现Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public Pelicula()
{
}
private int _listIndex = 0;
public void setListIndex(int value) {
_listIndex = value;
}
public int getListIndex() {
return _listIndex;
}
private ArrayList<ProgramacionPelicula> _presentandoceEn = new ArrayList<ProgramacionPelicula>();
public void addPresentandoceEn(ProgramacionPelicula programacion) {
_presentandoceEn.add(programacion);
}
public ArrayList<ProgramacionPelicula> getPresentandoceEn() {
return _presentandoceEn;
}
public void setPresentandose(Object[] programaciones) {
for (Object programacion : programaciones) {
if (programacion instanceof ProgramacionPelicula)
_presentandoceEn.add((ProgramacionPelicula) programacion);
}
}
}
public class ProgramacionPelicula实现了Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public ProgramacionPelicula() {
}
public ProgramacionPelicula(Pelicula pelicula) {
_pelicula = pelicula;
}
public ProgramacionPelicula(Cine cine) {
_cine = cine;
}
public String toString() {
if (getVista() == ProgramacionPelicula.VISTA_PELICULA)
return getCine().getCine();
else
return getPelicula().getTituloOriginal();
}
private int _idProgramacion;
public void setIdProgramacion(int value) {
_idProgramacion = value;
}
public int getIdProgramacion() {
return _idProgramacion;
}
private Pelicula _pelicula;
public void setPelicula(Pelicula pelicula) {
_pelicula = pelicula;
}
public Pelicula getPelicula() {
return _pelicula;
}
private Cine _cine;
public void setCine(Cine cine) {
_cine = cine;
}
public Cine getCine() {
return _cine;
}
public ArrayList<Tanda> _tandas = new ArrayList<Tanda>();
public void setTandas(ArrayList<Tanda> value) {
_tandas = value;
}
public void setTandas(Object[] tandas) {
for (Object tanda : tandas) {
if (tanda instanceof Tanda)
_tandas.add((Tanda) tanda);
}
}
public void addTanda(Tanda value) {
_tandas.add(value);
}
public ArrayList<Tanda> getTandas() {
return _tandas;
}
public String getListTandas() {
StringBuilder result = new StringBuilder();
for (Tanda tanda : getTandas()) {
result.append(" " + tanda.getDiaSemana());
result.append(" " + tanda.getDescripcion());
result.append(" " + tanda.getPrecio());
result.append("<br/>");
}
return result.toString();
}
private String _sala = "";
public void setSala(String value) {
_sala = value;
}
public String getSala() {
return _sala;
}
public static final int VISTA_CINE = 0;
public static final int VISTA_PELICULA = 1;
private int _vista = VISTA_CINE;
public int getVista() {
return _vista;
}
public ProgramacionPelicula toPelicula() {
ProgramacionPelicula programacionPelicula = new ProgramacionPelicula();
programacionPelicula._idProgramacion = _idProgramacion;
programacionPelicula._pelicula = _pelicula;
programacionPelicula._cine = _cine;
programacionPelicula._tandas = _tandas;
programacionPelicula._sala = _sala;
programacionPelicula._vista = VISTA_PELICULA;
return programacionPelicula;
}
}
提前致谢。
答案 0 :(得分:0)
序列化对象时,Java将遍历整个对象图。您的Cine
和Pelicula
类是否也实现了Serializable
接口?
答案 1 :(得分:0)
根据注释和堆栈,看起来你有一个循环引用,在写入对象时导致StackOverFlow。确保您的对象Pelicula,Cine,StreamData及其实例变量不是相互引用的。
您需要剪切参考,并确保没有循环参考。在您的情况下,可能是:
Pelicula和Cine都包含:
ArrayList<ProgramacionPelicula> _presentandoceEn
作为其实例变量,并且ProgramacionPelicula包含以下两个变量:
private Pelicula _pelicula; private Cine _cine;
可能会引用您在StreamData中尝试序列化的相同原始Pelicula或Cine对象,导致无限延续直到它抛出StackOverlow
您需要考虑重构您的课程以避免此类问题。从我看到的(我可能是错的),我认为你正在考虑存储电影/电视节目。在这种情况下,由于ProgramacionPelicula包含细节,您可能希望将其存储在StreamData中,并从Cine和Pelicula中删除ProgramacionPelicula的引用。从逻辑上讲,程序应包含详细信息,包括Cine和Pelicula对象,但Cine / Pelicula不应包含程序列表(尤其是引用自身的程序列表)。这是需要考虑的事情。
答案 2 :(得分:0)
Serializable是一个标记接口,但您可以实现自己的序列化规则和处理 只是覆盖:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
private void readObjectNoData()
throws ObjectStreamException;
更多http://download.oracle.com/javase/6/docs/api/java/io/Serializable.html