Android问题使用数组属性保存Serializable对象

时间:2011-09-04 17:44:34

标签: android serialization

大家好我正在实现序列化并在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;
}

}

提前致谢。

3 个答案:

答案 0 :(得分:0)

序列化对象时,Java将遍历整个对象图。您的CinePelicula类是否也实现了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