0

I am attempting to create a class that will contain methods for saving and loading an ArrayList of objects into SharedPreferences. However, when I attempt to load back data I had previously saved. It is as if it has not saved. I am using Googles Gson Libraries to help.

Instance_Read_Write.java

public class Instance_Read_Write {
    public void saveData(Context context, ArrayList<Example> Examples){
        SharedPreferences sharedPreferences = context.getSharedPreferences("instanceKey",Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        Gson gson = new Gson();
        String json = gson.toJson(Examples);
        editor.putString("list", json);
        editor.apply();
    }

    public void loadData(Context context, ArrayList<Example> Examples) {
        SharedPreferences sharedPreferences = context.getSharedPreferences("instanceKey",Context.MODE_PRIVATE);
        Gson gson = new Gson();
        String json = sharedPreferences.getString("list", null);
        Type type = new TypeToken<ArrayList<Example>>() {}.getType();
        Examples = gson.fromJson(json, type);

        if (Examples == null) {
            Examples = new ArrayList<>();
        }
    }

}

and this is how I am referencing them.

MainActivity.java

Instance_Read_Write instance_read_write = new Instance_Read_Write();
instance_read_write.loadData(context,Examples);
Examples.add(new Example("test"));

    ...
    ...
    ...

   instance_read_write.saveData(context,Examples);

Is there a way to make this work? or perhaps a better way to do this?

Bowman
  • 27
  • 1
  • 3
  • 1
    Your `loadData` does not look correct - you pass in `Examples` but then override it with the result of `gson.fromJson` and so it is never returned. You would need to operate on Examples such as `.add` or `.addAll`. –  Sep 07 '20 at 08:10
  • I am a little confused, do you mean something along the lines of .add(gson.fromJson(json, type));? Something like this throws me NullPointerExceptions as is the case with AddAll(), I believe I just don't understand what you mean. – Bowman Sep 07 '20 at 14:46
  • I have tried making these methods local in the classes I use them, they do work in there current state, minus the arguments. Could it perhaps be my arguments? Contexts is essentially "this", and my ArrayList Examples is a reference to my passed ArrayList I am looking to manipulate. – Bowman Sep 07 '20 at 14:53

2 Answers2

0

Instead of the Token for the Type, put

Examples = gson.fromJson(json, Example.class);

Tell me if it works

Kevin Gilles
  • 463
  • 1
  • 8
  • 23
  • Hey thanks for your reccomendation, however nothing happens. The fromJson() requests a Type as its second argument. So when I cast Example.class, its has if nothing changed sadly. – Bowman Sep 07 '20 at 14:48
0

This addresses one error in your posted code namely the treatment of the Examples parameter in the method loadData method.

Since it seems your intention of the loadData is to always produce an ArrayList then I'd recommend returning the instance. Alternatively, you would have to first create an empty ArrayList and pass that in and then operate on it.

So using the approach of returning the ArrayList:

public ArrayList<Example> loadData(Context context) {
    ArrayList<Example> result;
    SharedPreferences sharedPreferences = context.getSharedPreferences("instanceKey",Context.MODE_PRIVATE);
    Gson gson = new Gson();
    String json = sharedPreferences.getString("list", null);
    Type type = new TypeToken<ArrayList<Example>>() {}.getType();
    result = gson.fromJson(json, type);

    if (result == null) {
        result = new ArrayList<>();
    }
    return result;
}

// ... and the calling code (in MainActivity) looks like:
Examples = instance_read_write.loadData(context);

Not to stoke up a pass-by-value vs pass-by-reference discussion - it appears you are expecting Example actual parameter to be updated by assigning it in the body of the method - which it will not - you can only operate on the object to affect it: https://stackoverflow.com/a/40523/2711811.

To complete the topic, here's a solution which would continue your intention of passing in the Examples object:

// In calling method...
Examples = new ArrayList<Example>;
instance_read_write.loadData(context,Examples);



//...in class Instance_Read_Write...

public void loadData(Context context, ArrayList<Example> Examples) {
    SharedPreferences sharedPreferences = context.getSharedPreferences("instanceKey",Context.MODE_PRIVATE);
    Gson gson = new Gson();
    String json = sharedPreferences.getString("list", null);
    Type type = new TypeToken<ArrayList<Example>>() {}.getType();
    ArrayList<Example> t = gson.fromJson(json, type);
   
    if (t != null) {
        Examples.addAll(t);
    }
}