M.Ghali
M.Ghali

Reputation: 97

Save an object or list of objects in Android

I have a list of a custom object class that I called Students, and I would like to save it in a way such that it won't be affected when we close the app completely. The class: (of course I have a constructor and stuff, but these are the fields that may be important)

public class Students implements Serializable{
private int ID;
private int imageId;
private String firstName;
private String lastName;
private Map<Date, Boolean> Attendance;

My attempt in saving and reading it (inside an activity):

public Boolean saveStudent(Students s) {//saves student into fileName (data.bin)
    ObjectOutputStream oos = null;
    try {
        File file = new File(this.getFilesDir().toString(), fileName);
        file.createNewFile();
        if(!file.mkdir()){ //just to check whats the reason behind the failed attempt
            Toast.makeText(this, "Security Issue", Toast.LENGTH_SHORT).show();
        }
        FileOutputStream fos = this.openFileOutput(fileName, this.MODE_PRIVATE);
        oos = new ObjectOutputStream(fos);
        oos.writeObject(s);
        oos.close();
        fos.close();
        return true;
    } catch (FileNotFoundException err) {
        Toast.makeText(this, "Something went wrong while saving", Toast.LENGTH_SHORT).show();
        return false;
    } catch (Exception abcd) {
        Toast.makeText(this, "Ooops, I don't know what's the problem. Sorry about that!", Toast.LENGTH_SHORT).show();
        return false;
    }
    finally {//makes sure to close the ObjectOutputStream
        if (oos != null) {
            try {
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


public Students readStudent() {//reads Student object from(data.bin) and returns it.
    ObjectInputStream ois = null;
    try {
        ois = new ObjectInputStream(new FileInputStream("data.bin"));
        ois.close();
        return (Students) ois.readObject();
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        return null;
    } finally {
        if (ois != null) {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

When I run, it gives me the "Something went wrong while saving" and "Security Issue". Can some one help me solve this problem?

PS: I really don't wanna use an SQLlite database because I think that it's an overkill for just 3 or 4 entries. I hope it's not one of those stupid mistakes that take several hours of staring to find out.

Upvotes: 2

Views: 608

Answers (2)

Sunhee
Sunhee

Reputation: 111

Please check this source. I have tested it, and it is working well.

public class LoginActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Students students = new Students();
        students.setID(1234);
        students.setFirstName("hello");
        Log.d("test", "pre students="+students);
        saveStudent(students);

        Students s = readStudent();
        Log.d("test", "after students="+s);

    }

    String fileName = "data.bin";

    public Boolean saveStudent(Students s) {//saves student into fileName (data.bin)
        ObjectOutputStream oos = null;
        try {
           /* File file = new File(this.getFilesDir().toString(), fileName);
            file.createNewFile();
            if(!file.mkdir()){ //just to check whats the reason behind the failed attempt
                Toast.makeText(this, "Security Issue", Toast.LENGTH_SHORT).show();
            }*/
            FileOutputStream fos = this.openFileOutput(fileName, this.MODE_PRIVATE);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(s);
            oos.close();
            fos.close();
            return true;
        } catch (FileNotFoundException err) {
            Toast.makeText(this, "Something went wrong while saving", Toast.LENGTH_SHORT).show();
            return false;
        } catch (Exception abcd) {
            Toast.makeText(this, "Ooops, I don't know what's the problem. Sorry about that!", Toast.LENGTH_SHORT).show();
            return false;
        }
        finally {//makes sure to close the ObjectOutputStream
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public Students readStudent() {//reads Student object from(data.bin) and returns it.
        ObjectInputStream ois = null;
        Students students = new Students();
        try {
            /*ois = new ObjectInputStream(new FileInputStream("data.bin"));*/
            ois = new ObjectInputStream(openFileInput(fileName));
            students = (Students) ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return students;
    }
}

And for saving and loading multiple objects, please check this link How do I save and multiple objects from a single file?

Upvotes: 2

Rust Fisher
Rust Fisher

Reputation: 341

No need to file.mkdir()

Give openFileOutput an absolutePath may be good.

Check here:

File file = new File(this.getFilesDir().toString(), fileName);
file.createNewFile();
//if(!file.mkdir()){ //just to check whats the reason behind the failed attempt
//    Toast.makeText(this, "Security Issue", Toast.LENGTH_SHORT).show();
//}
// Use file.getAbsolutePath()
FileOutputStream fos = this.openFileOutput(file.getAbsolutePath(), this.MODE_PRIVATE);
oos =oos = new ObjectOutputStream(fos);
oos.writeObject(s);
oos.close();
fos.close();
return true;

And in the read method you should give an absolute file path

check this line : ois = new ObjectInputStream(new FileInputStream("data.bin"));

pass more information to the new FileInputStream("data.bin")

change to :new FileInputStream(new File(getContext().getFilesDir(),"data.bin"));

Do not forget the parent dir.

Upvotes: 1

Related Questions