Pableras84
Pableras84

Reputation: 1195

ObjectInputStream gives me an empty object (but the readed file is not empty)

I have this serializable class, wich i use to store on a binary file an ArrayList of Strings.

public class SaveState implements Serializable{
   public static ArrayList <String> favoriteBusStopNumbers = new ArrayList<String>();
   public static SaveState instance=new SaveState();
}

I'm using this method to store the instance with the arrayList of strings once this array is full with the data i must store:

public static void saveData(){
    ObjectOutput out;
    try {
        //primero comprobamos si existe el directorio, y si no, lo creamos.
        File folder = new File(Environment.getExternalStorageDirectory() + DIRECTORY_NAME);
        if(!folder.exists())
            folder.mkdirs();

        File outFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data");
        out = new ObjectOutputStream(new FileOutputStream(outFile)); 
        out.writeObject(SaveState.instance);
        out.close();
    } catch (Exception e) {e.printStackTrace();}
}

And finally, i use this method on the init of my app to load the file and fill my SaveState.instance variable with the previously stored data:

public static void loadData(){
    ObjectInput in;
    try {
        File inFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data");
        in = new ObjectInputStream(new FileInputStream(inFile));        
        SaveState.instance=(SaveState) in.readObject();
        in.close();
    } catch (Exception e) {e.printStackTrace();}
}

When i save the data, the file is being created correctly with the object fill of data, i know it because the file has more than 0KB of disc space. But something is going wrong here because when i start my app and load the data, my SaveState.instance variable gets an empty ArrayList of strings....... then ¿what is wrong in the code?

Thanks

Upvotes: 4

Views: 2195

Answers (3)

Kal
Kal

Reputation: 24910

Your arraylist is static. Static variables are associated with the class and not with the object. So they dont get serialized.

If you do want to serialize static variables, you have to override readObject and writeObject.

Here is some additional info -- http://java.sun.com/developer/technicalArticles/Programming/serialization/

Best solution here is to reconsider your data structure and make the arraylist non-static if its saving the state of an object.

EDIT: Alternatively, you could serialize just the arraylist ( as @Ted suggests below )

Upvotes: 6

Pr0gr4mm3r
Pr0gr4mm3r

Reputation: 6230

The problem is that variables marked as static will not be serialized except you implement

private void readObject(ObjectInputStream ois){}  

and

private void writeObject(ObjectOutputStream oos){}

ObjectOutputStream - JavaDoc:

The default serialization mechanism for an object writes the class of the object, the class signature, and the values of all non-transient and non-static fields.

Upvotes: 3

Ted Hopp
Ted Hopp

Reputation: 234795

Since the only data kept in SaveState is a static array, you'll have more success just serializing and deserializing the array:

public static void saveData(){
    ObjectOutput out;
    try {
        //primero comprobamos si existe el directorio, y si no, lo creamos.
        File folder = new File(Environment.getExternalStorageDirectory() + DIRECTORY_NAME);
        if(!folder.exists())
            folder.mkdirs();

        File outFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data");
        out = new ObjectOutputStream(new FileOutputStream(outFile)); 
        out.writeObject(SaveState.favoriteBusStopNumbers);
        out.close();
    } catch (Exception e) {e.printStackTrace();}
}

@SuppressWarnings("unchecked")
public static void loadData(){
    ObjectInput in;
    try {
        File inFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data");
        in = new ObjectInputStream(new FileInputStream(inFile));
        SaveState.favoriteBusStopNumbers=(ArrayList<String>) in.readObject();
        in.close();
    } catch (Exception e) {e.printStackTrace();}
}

(You need to suppress the warning about casting to a generic type.)

You don't really need the SaveState.instance field at all.

Upvotes: 1

Related Questions