Search code examples
androidarraylistsharedpreferencespojogson

ArrayList of custom objects not saving to SharedPreferences with GSON


I have an ArrayList of custom POJO objects that I want to save to SharedPreferences so they don't get garbage collected and the user can still access them after the application is closed.

I have tried using GSON but I think there's something I'm missing which I can't see.The String my Object is converted to has been saved properly but nothing is stored in it.

I'm using this Click event to store:

cartBut.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(getBaseContext(), "Clicked", Toast.LENGTH_SHORT).show();
            SharedPreferences mPrefs = getSharedPreferences("Cart", MODE_PRIVATE);
            SharedPreferences.Editor prefsEditor = mPrefs.edit();

            ArrayList<ItmModel> arrayList = new ArrayList<>();
            AtomicReference<ItmModel> itmModel = new AtomicReference<>(new ItmModel(item.getText().toString(), attr.getText().toString(),
                    pric.getText().toString(), sise.getText().toString(), image, company));
            arrayList.add(itmModel.get());

            Gson gson = new Gson();
            Type type = new TypeToken<ArrayList<ItmModel>>() {
            }.getType();
            String list = gson.toJson(arrayList, type);
            prefsEditor.putString("Cart", list);
            prefsEditor.apply();

        }
    });

and I'm retrieving it like this:

SharedPreferences sharedPreferences = getSharedPreferences("Cart", MODE_PRIVATE);
    Gson gson = new Gson();
    String list = sharedPreferences.getString("Cart", "");
    Type type = new TypeToken<ArrayList<ItmModel>>() {
    }.getType();
    arrayList = gson.fromJson(list, type);
    if (arrayList == null) {
        arrayList = new ArrayList<>();
    }

    final CrtAdapter crtAdapter = new CrtAdapter(arrayList);

    RecyclerView recyclerView = view.findViewById(R.id.recyclerView);
    recyclerView.setAdapter(crtAdapter);
    recyclerView.setHasFixedSize(true);
    recyclerView.setItemViewCacheSize(20);
    recyclerView.setDrawingCacheEnabled(true);
    recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    recyclerView.setLayoutManager(linearLayoutManager);
    runLayoutAnimation(recyclerView);
    recyclerView.setOnFlingListener(null);

Despite all my attempts, the RecyclerView is always empty and when I check in my File explorer the Preference is empty like in this screenshotPic 1

and this

Pic 2

My POJO is both Parcelable and Serializable. What could I be doing wrong? I'll post any required code. Thank you.

This is what i'm getting from the logs in the click event.I see the object is added but later removed from the list.Why could that be happenig?

04-06 09:53:42.959 4078-4078/kamble.gml.woodleyint D/dalvikvm: create interp thread : stack size=128KB
04-06 09:53:42.959 4078-4078/kamble.gml.woodleyint D/dalvikvm: create new thread
04-06 09:53:42.959 4078-4078/kamble.gml.woodleyint D/dalvikvm: new thread created
04-06 09:53:42.959 4078-4078/kamble.gml.woodleyint D/dalvikvm: update thread list
04-06 09:53:42.959 4078-4455/kamble.gml.woodleyint D/dalvikvm: threadid=26: interp stack at 0x57bee000
04-06 09:53:42.959 4078-4455/kamble.gml.woodleyint D/dalvikvm: threadid=26: created from interp
**04-06 09:53:42.960 4078-4078/kamble.gml.woodleyint D/dalvikvm: threadid=26: adding to list**
04-06 09:53:42.960 4078-4078/kamble.gml.woodleyint D/dalvikvm: start new thread
04-06 09:53:42.960 4078-4455/kamble.gml.woodleyint D/dalvikvm: threadid=26: notify debugger
04-06 09:53:42.960 4078-4455/kamble.gml.woodleyint D/dalvikvm: threadid=26 (SharedPreferencesImpl-load): calling run()
04-06 09:53:42.968 4078-4455/kamble.gml.woodleyint D/dalvikvm: threadid=26: exiting
04-06 09:53:42.968 4078-4455/kamble.gml.woodleyint D/dalvikvm: threadid=26: detach (group=0x418d8ce0)
**04-06 09:53:42.968 4078-4455/kamble.gml.woodleyint D/dalvikvm: threadid=26: removing from list
04-06 09:53:42.968 4078-4455/kamble.gml.woodleyint D/dalvikvm: threadid=26: bye!
04-06 09:53:43.143 4078-4078/kamble.gml.woodleyint D/Cart: [[]]**
04-06 09:53:43.146 4078-4078/kamble.gml.woodleyint D/dalvikvm: create interp thread : stack size=128KB
04-06 09:53:43.146 4078-4078/kamble.gml.woodleyint D/dalvikvm: create new thread
04-06 09:53:43.146 4078-4078/kamble.gml.woodleyint D/dalvikvm: new thread created
04-06 09:53:43.146 4078-4078/kamble.gml.woodleyint D/dalvikvm: update thread list
04-06 09:53:43.146 4078-4456/kamble.gml.woodleyint D/dalvikvm: threadid=26: interp stack at 0x57bee000
04-06 09:53:43.146 4078-4456/kamble.gml.woodleyint D/dalvikvm: threadid=26: created from interp
**04-06 09:53:43.146 4078-4078/kamble.gml.woodleyint D/dalvikvm: threadid=26: adding to list**
04-06 09:53:43.146 4078-4078/kamble.gml.woodleyint D/dalvikvm: start new thread
04-06 09:53:43.152 4078-4456/kamble.gml.woodleyint D/dalvikvm: threadid=26: notify debugger
04-06 09:53:43.152 4078-4456/kamble.gml.woodleyint D/dalvikvm: threadid=26 (pool-3-thread-1): calling run()

This is my POJO:

public class ItmModel extends ArrayList implements Parcelable, Serializable {
@SuppressWarnings("unused")
public static final Parcelable.Creator<ItmModel> CREATOR = new Parcelable.Creator<ItmModel>() {
    @Override
    public ItmModel createFromParcel(Parcel in) {
        return new ItmModel(in);
    }

    @Override
    public ItmModel[] newArray(int size) {
        return new ItmModel[size];
    }
};
private String name;
private String attr;
private String size;
private String pric;
private String imag;
private String comp;

public ItmModel(String name, String attr, String size, String pric, String imag, String comp) {
    this.name = name;
    this.attr = attr;
    this.size = size;
    this.pric = pric;
    this.imag = imag;
    this.comp = comp;
}

public ItmModel() {

}

private ItmModel(Parcel in) {
    name = in.readString();
    attr = in.readString();
    size = in.readString();
    pric = in.readString();
    imag = in.readString();
    comp = in.readString();
}

public String getName() {
    return name;
}

public void setName(String companyName) {
    this.comp = companyName;
}

public String getAttr() {
    return attr;
}

public void setAttr(String attr) {
    this.attr = attr;
}

public String getSize() {
    return size;
}

public void setSize(String size) {
    this.size = size;
}

public String getPric() {
    return pric;
}

public void setPric(String pric) {
    this.pric = pric;
}

public String getImag() {
    return imag;
}

public void setImag(String imag) {
    this.imag = imag;
}

public String getComp() {
    return comp;
}

public void setComp(String comp) {
    this.comp = comp;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeString(attr);
    dest.writeString(size);
    dest.writeString(pric);
    dest.writeString(imag);
    dest.writeString(comp);
}}

Solution

  • Try to remove AtomicReference and add item to list directly as in

    ArrayList<ItmModel> arrayList = new ArrayList<>();
    ItmModel itmModel = new ItmModel(item.getText().toString(), attr.getText().toString(),pric.getText().toString(), sise.getText().toString(), image, company);
    arrayList.add(itmModel);
    
    Gson gson = new Gson();
    Type type = new TypeToken<ArrayList<ItmModel>>() {}.getType();
    String list = gson.toJson(arrayList, type);
    prefsEditor.putString("Cart", list);
    prefsEditor.apply();
    

    Why are you even extending ArrayList in POJO, remove and modify part of your POJO to below

    public class ItmModel implements Parcelable, Serializable {
    @SuppressWarnings("unused")
    public static final Parcelable.Creator<ItmModel> CREATOR = new Parcelable.Creator<ItmModel>() {
        @Override
        public ItmModel createFromParcel(Parcel in) {
            return new ItmModel(in);
        }
    
        @Override
        public ItmModel[] newArray(int size) {
            return new ItmModel[size];
        }
    };
    @Expose
    private String name;
    @Expose
    private String attr;
    @Expose
    private String size;
    @Expose
    private String pric;
    @Expose
    private String imag;
    @Expose
    private String comp;
     //rest of code as it is
    }