I’m trying to serialize an object and store it on the SD card. Essentially I am saving the game state. So I just serialize a single object called GameState, which itself contains various other objects and primitives, the objects are all serializable.
Now serializing and saving the file works fine. No errors or exceptions in the logcat. However, about fifty percent of the time when trying to deserialize the GameState I get an exception, java.io.OptionalDataException .
My deserialization method looks like this:
...
try {
File sdCard = Environment.getExternalStorageDirectory();
instream = new FileInputStream(sdCard.getAbsolutePath()+"/my_app/saved_game");
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
try {
ObjectInputStream ois = new ObjectInputStream(instream);
try {
g= (GameState) ois.readObject();
try {
instream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return g;
} catch (ClassNotFoundException ex) {
return null;
}
} catch (StreamCorruptedException ex) {
return null;
} catch (IOException ex) {
return null;
}
What I can’t figure out is why it only fails sometimes. I have implemented similar de/serialization methods in other apps with no problems, so I’m getting confused. GameState contains no static or transient fields.
This is the logcat
03-05 23:18:35.458: WARN/System.err(7588):
java.io.OptionalDataException 03-05 23:18:35.458:
WARN/System.err(7588): at
java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:966)
03-05 23:18:35.458: WARN/System.err(7588): at
java.io.ObjectInputStream.readObject(ObjectInputStream.java:2299)
03-05 23:18:35.458: WARN/System.err(7588): at
java.io.ObjectInputStream.readObject(ObjectInputStream.java:2254)
03-05 23:18:35.468: WARN/System.err(7588): at
java.util.ArrayList.readObject(ArrayList.java:674) 03-05 23:18:35.468:
WARN/System.err(7588): at
java.lang.reflect.Method.invokeNative(Native Method) 03-05
23:18:35.468: WARN/System.err(7588): at
java.lang.reflect.Method.invoke(Method.java:521) 03-05 23:18:35.468:
WARN/System.err(7588): at
java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1551)
03-05 23:18:35.468: WARN/System.err(7588): at
java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1474)
03-05 23:18:35.468: WARN/System.err(7588): at
java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:2153)
03-05 23:18:35.468: WARN/System.err(7588): at
java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:943)
03-05 23:18:35.468: WARN/System.err(7588): at
java.io.ObjectInputStream.readObject(ObjectInputStream.java:2299)
03-05 23:18:35.468: WARN/System.err(7588): at
java.io.ObjectInputStream.readObject(ObjectInputStream.java:2254)
03-05 23:18:35.468: WARN/System.err(7588): at
java.io.ObjectInputStream.readFieldValues(ObjectInputStream.java:1319)
03-05 23:18:35.468: WARN/System.err(7588): at
java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:540)
03-05 23:18:35.468: WARN/System.err(7588): at
java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1566)
03-05 23:18:35.468: WARN/System.err(7588): at
java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1474)
03-05 23:18:35.468: WARN/System.err(7588): at
java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:2153)
I have solved the problem, and I am ashamed to say it was because I forgot to implement Serializable in one class that was rarely used. That’s why it usually de/serialized fine. Only when an instance of that class was present did things go wrong.