4

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

Pableras84
  • 1,195
  • 5
  • 18
  • 30

3 Answers3

6

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 )

Kal
  • 24,724
  • 7
  • 65
  • 65
  • I'm not using `static` and yet my arraylist object is blank after `readObject()`. Any clues on this issue? – Suresh Nov 09 '18 at 10:42
3

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.

Pr0gr4mm3r
  • 6,170
  • 1
  • 18
  • 23
1

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.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521