开发者

Android Problem Saving Serializable object with array attributes

Hi everybody I'm implementing serialization and saving object in the android device memory. I have a class that i use to save and get the object. The problem is that the class that i want to save has attributes that are array list of other objects that i have in my app and when i try to save it I get an unknown from the application.

Below the code of both classes:

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<Peli开发者_Go百科cula> _proximamente = new ArrayList<Pelicula>();

public int getIdStream() {
    return _idStream;
}

public void setIdStream(int value) {
    _idStream = value;
}

public int getIdMensaje() {
    return _idMensaje;
}


}

UPDATE: I see in the logcat debbuger this:

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

Code for the others classes

public class Cine implements 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);
}

}

public class Pelicula implements 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 implements 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;
}

}

Thanks in advance.


Based on the comments and the stack, it looks like you have circular reference that is causing StackOverFlow when writing the object. Make sure your objects Pelicula, Cine, StreamData and its instance variable are not referring each other.

You need to cut the reference and make sure you don't have circular reference. In your case, it's likely that:

Both Pelicula and Cine contain:

ArrayList<ProgramacionPelicula> _presentandoceEn

as its instance variable and following that ProgramacionPelicula contains these two variables:

private Pelicula _pelicula;
private Cine _cine;

which could refer back to the same original Pelicula or Cine object that you are trying to serialize in the StreamData causing to go on infinitely until it throws StackOverlow

You need to consider to restructure your classes to avoid this kind of problem. From what I see (and I might be wrong), I think you are thinking to store the movies/TV program. In this case since ProgramacionPelicula contains the details, you probably want to store that instead in StreamData and cut the reference of ProgramacionPelicula from both Cine and Pelicula. Logically the program should contains the details including the Cine and Pelicula object, but Cine/Pelicula shouldn't contains the list of programs (especially the one that refers back to themselves). It's something to consider.


When you serialize an object, Java will walk through the entire object graph. Are your Cine and Pelicula classes implementing the Serializable interface as well?


Serializable is a marker Interface but you can implement your own serializing rules and handling just override:

 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;
 private void readObjectNoData() 
     throws ObjectStreamException;

more at http://download.oracle.com/javase/6/docs/api/java/io/Serializable.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜