I’m using the following code to save and retrieve objects to and from the Androids internal memory. I have tested it with a string object with success. When I try to save a Bitmap I get a IOException. (I found out that I have to call the compress method) So I notice that I can save some objects, what are the restrictions to saving objects?
When I save a object, does it only save the fields? Can I save objects that contains other objects? Please clear me up.
Code:
public Object readObjectFromMemory(String filename) {
Object defautObject = null;
FileInputStream fis;
try {
fis = game.openFileInput(filename);
ObjectInputStream is = new ObjectInputStream(fis);
defautObject = is.readObject();
is.close();
this.gameEngineLog.d(classTAG, "Object successfully read: " + filename);
}
catch (FileNotFoundException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "FileNotFoundException");
this.gameEngineLog.d(classTAG, "Object couldn't be opened: " + filename);
}
catch (StreamCorruptedException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "StreamCorruptedException");
this.gameEngineLog.d(classTAG, "Object couldn't be opened: " + filename);
}
catch (IOException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "IOException");
this.gameEngineLog.d(classTAG, "Object couldn't be opened: " + filename);
}
catch (ClassNotFoundException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "ClassNotFoundException");
this.gameEngineLog.d(classTAG, "Object couldn't be opened: " + filename);
}
return defautObject;
}
public void writeObjectToMemory(String filename, Object object) {
FileOutputStream fos;
try {
fos = game.openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(object);
os.close();
this.gameEngineLog.d(classTAG, "Object successfully written: " + filename);
}
catch (FileNotFoundException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "Object couldn't be written: " + filename);
}
catch (IOException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "Object couldn't be written: " + filename);
}
}
Thanks in advance.
The restriction is that all objects have to be serializable (implement the interface Serializable). If an object data member of an object is not serializable, it has to be marked as transient:
EDIT about serializing non-serializable members
It depends on what you are trying to serialize that is not serializable. Since this is a question tagged with Android it could be a Context object for example.
Contexts are not serializable for a good reason, they are tied to a life cycle, either of the application or of an Activity. Its state is volatile and even if you could serialize and deserialize it later, its internal state wouldn’t make sense, since a new Context has been established, a new thread or even a different process may be running by now.
In case of data members like Contexts you need to declare them as transient and re-assign the fresh and valid current Context to the deserialized object.
If you are trying to serialize different kinds of objects that on the one hand just represent data like a bunch of strings and / or numbers, but on the other hand are not serializable, you have two options:
Customization can be done by implementing the methods
These methods are invoked on serialization / deserialization of the class. The trick is to take the data / state of a non-serializable object and pack that data into a serializable object instead. You could for example use any Collection object like an ArrayList for sequentially storing the raw data.
Let’s assume you want to serialize a Location object (for geo location coordinates) and let’s also assume that object is not serializable. But you know that it consists of three values which can be serialized:
You could store these three values in an ArrayList or you could create your own custom, serializable class which stores these values for serialization purposes.
Put the ArrayList or your serializable intermediate object into the ObjectOutputStream of your custom writeObject method.
In readObject you need to reverse these steps and reconstruct your data member that is not serializable based on the raw data you serialized.
I also suggest reading Sun’s documentation about serialization