Save and Retrieving ArrayList to SharedPreferences - java

This is my Saving Program Code this will save the score, date and the player name to the leaderboard:
mLeaderboardlist = new ArrayList<>();
Leaderboardmodel s = new Leaderboardmodel();
s.setDate("07/24/17");
s.setName(player.getText().toString());
s.setScore(Integer.parseInt(String.valueOf(yourScore.getText())));
Tab1Normal.mLeaderboardlist.add(s);
SharedPreferences appSharedPrefs = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor prefsEditor = appSharedPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(s);
prefsEditor.putString("MyObject", json);
prefsEditor.apply();
prefsEditor.commit();
And this is my retrieving program code of dealing also in sharedpreference:
SharedPreferences appSharedPrefs = PreferenceManager
.getDefaultSharedPreferences(this.getActivity().getApplicationContext());
Gson gson = new Gson();
String json = appSharedPrefs.getString("MyObject", "");
Type type = new TypeToken<ArrayList<Leaderboardmodel>>(){}.getType();
ArrayList<Leaderboardmodel> leaderboard= gson.fromJson(json, type);
Collections.sort(leaderboard);
adapter = new ListLeaderBoardAdapter(getActivity(), leaderboard);
lvLeaderboardlist.setAdapter(adapter);
The save saving part work fines but the retrieving part display an error and makes the application crash, the error display :
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

The problem is that you put an object, not a json.
Leaderboardmodel s = new Leaderboardmodel();
....
String json = gson.toJson(s);
prefsEditor.putString("MyObject", json);
You need to put your array
mLeaderboardlist = new ArrayList<>();
...
String json = gson.toJson(mLeaderboardlist );

Try to debug into your loaded json and see if you really get valid json String.
There is also already a similar question on so: Parsing generic ArrayList using GSON

When you are saving you are saving object not arraylist,
String json = gson.toJson(s);
here s is object of Leaderboardmodel and not arraylist of Leaderboardmodel
So when you retrieve, retrieve it as object not array list like,
Type type = new TypeToken<Leaderboardmodel>(){}.getType();
Leaderboardmodel leaderboard= gson.fromJson(json, type);

Change this line
ArrayList<Leaderboardmodel> leaderboard= gson.fromJson(json, type);
to this
Leaderboardmodel[] leaderboard= gson.fromJson(json, Leaderboardmodel[].class);
and see if it works.
I hope so.
Update:
You need to create an array list of Leaderboardmodel , then call sort.
ArrayList<Leaderboardmodel > leaderboardmodels = new ArrayList<>();
leaderboardmodels.addAll(leaderboard);
Collections.sort(leaderboardmodels);

Related

Retrieve hashmap data SharedPreferences

I used HashMap to store data which I received using API. After that, I used SharedPreferences to store the received HashMap data. Storing part is done. I can see the number of records which I wanted to store using SharedPreferences.
Here is the code to save data:
if (result != null && result.length() > 0)
{
for (int j = 0; j < result.length(); j++)
{
JSONObject resultObj = result.getJSONObject(j);
String label_id = resultObj.getString("label_id");
String arabic = resultObj.getString("arabic");
String english = resultObj.getString("english");
String key = resultObj.getString("key");
//Create a new model and set the received value
LabelModel labelModel = new LabelModel();
labelModel.setLabelId(label_id);
labelModel.setArabic(arabic);
labelModel.setEnglish(english);
labelModel.setKey(key);
int label = Integer.parseInt(label_id);
//Put the value
map.put(label, labelModel);
}
}
//With the below line, I stored the hashMap data using SharedPreferences
Pref.setValue(mActivity, AppPrefrences.PREF_LABELS, map);
After the above steps, I followed this set of code to set and get the value from SharePreferences, which I stored in application using SharedPreferences.
For that, I used this below code:
public static String PREF_LABELS ="labels";
public static void setValue(#NonNull Context context, String key, Object obj) {
Pref.openPref(context);
Editor prefsPrivateEditor = Pref.sharedPreferences.edit();
prefsPrivateEditor.putString(key, String.valueOf(obj));
prefsPrivateEditor.commit();
prefsPrivateEditor = null;
Pref.sharedPreferences = null;
}
#Nullable
public static String getValue(#NonNull Context context, String key, Object obj) {
Pref.openPref(context);
String result = Pref.sharedPreferences.getString(key, String.valueOf(obj));
Pref.sharedPreferences = null;
return result;
}
Now, I am trying to retrieve the data which I stored in SharedPreferences.
Here is the code I used to retrieve the data:
String labels = Pref.getValue(mActivity, AppPrefrences.PREF_LABELS, "");
When I debug the app, I get values in Labels below format. The same number of records I received.
The format goes like this:
{572=com.*****.landlord.model.LabelModel#23a282e, 598=com.*****.landlord.model.LabelModel#c954fcf, 590=com.*****.landlord.model.LabelModel#2fe3d5c, 103=com.*****..........}
How can I get the each data from this format?
There is no support for HashMap in SharedPreferences. So, you can't save the HashMap by converting it to a string directly, but you can convert it to JSON string. You can use google-gson in this case. Something like this:
First, include the dependency:
compile 'com.google.code.gson:gson:2.8.2'
Saving from HashMap object to preference:
Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(map);
prefsEditor.putString("YourHashMap", json);
prefsEditor.commit();
Get HashMap object from preference:
Gson gson = new Gson();
String json = mPrefs.getString("YourHashMap", "");
HashMap map = gson.fromJson(json, HashMap.class);
Instead convert the map to gson String and store it in preference like this
//convert to string using gson
Gson gson = new Gson();
String mapString = gson.toJson(map);
//save this in the shared prefs
SharedPreferences prefs = getSharedPreferences("test", MODE_PRIVATE);
prefs.edit().putString("yourkey", mapString).apply();
//get from shared prefs in gson and convert to maps again
String storedHashMapString = prefs.getString("yourkey",null);
java.lang.reflect.Type type = new TypeToken<HashMap<String, String>>(){}.getType();
//Get the hashMap
HashMap<String, String> map = gson.fromJson(storedHashMapString, type);
You are getting {572=com.*****.landlord.model.LabelModel#23a282e, 598=com.*****.landlord.model.LabelModel#c954fcf, 590=com.*****.landlord.model.LabelModel#2fe3d5c, 103=com.*****..........} this because Object default toString() method use hashcode.
Storing complex object in SharedPreference is not recommended. SharedPreference don't support HashMap link.
For storing simple object you have to convert the object into String using toString() method.
You can use Gson for converting object to String and that will be a easy solution.
You can also use ObjectOutputStream to write it to the internal memory check this link
You should cast lables string into hashmap object This is one solution. If you want to make it more generic, you can us StringUtils library.
String value = "{first_name = mohit,last_name = mathur,gender = male}";
value = value.substring(1, value.length()-1); //remove curly brackets
String[] keyValuePairs = value.split(","); //split the string to creat key-value pairs
Map<String,String> map = new HashMap<>();
for(String pair : keyValuePairs) //iterate over the pairs
{
String[] entry = pair.split("="); //split the pairs to get key and value
map.put(entry[0].trim(), entry[1].trim()); //add them to the hashmap and trim whitespaces
}
For example, you can switch
value = value.substring(1, value.length()-1);
to
value = StringUtils.substringBetween(value, "{", "}");
and after that
You should cast value in LabelModel
like
LabelModel labels = map.get("598");
SharedPreference doesn't support store map object. https://developer.android.com/reference/android/content/SharedPreferences.Editor.html. So your code just store data obj.toString, that why you see result in debug. If you want to store a map, you can store as json and use put string.

Convert List<MyDTO> to List<Map<String,String>> using Gson

I have DTO as below :
public class MyDTO {
private String MEValueName;
private String MyId;
// getters and setters
}
Gson gson = new Gson();
List<MyDTO> list = new ArrayList<MyDTO>();
MyDTO dto = new MyDTO();
dto.setMEValueName("raghu");
dto.setMyId("qwer");
MyDTO dto1 = new MyDTO();
dto1.setMEValueName("raghuveer");
dto1.setMyId("qwer1");
list.add(dto);
list.add(dto1);
String json = gson.toJson(list);
System.out.println(json);
// below line is failing
List<Map<String, String>> list1 = gson.fromJson(json, new TypeToken<List<Map<String, String>>>(){}.getType());
System.out.println(list1);
when i run this i get the follow error :
java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 11 path $[0].
Also i want to use a generic type so that i can use other DTOs also to convert to list of map. Kindly suggest.
I see two immediate problems...
The json-string is of an object of type List<MyDTO>.
gson.fromJson must have a TypeToken of that same object type.
And even if the fromJson worked, you cant assign List<MyDTO> to a list of type List<Map<String,String>>.
Edit (doing this by memory so it might need some fine tuning to compile):
List<Map<String, String>> list1 = new List();
Map<String,String> map = new HashMap<>();
list1.add(map);
map.add("some key",json);

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2, jsonSyntax Error

I want to save Hashset Object in to Sharedpreference and than want retrieve that data. I am storing data in to hashset and and converting object in to json using Gson. Actually m storing bitmap in to Hashset. I am able to convert and save Hashsetobject into sharedpreference. I am getting problem when I am retrieving and converting json to Hashset Object.
HashSet<images> img = new HashSet<images>(CIRCLES_LIMIT);
Here is Method For Saving Object in to Sharedpreference.
public void saveString() throws JSONException {
Object spSquare = c.getStringDrawObjImages();
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor editor = sharedPrefs.edit();
Gson gson = new Gson();
String jsonSquare = gson.toJson(spSquare)
editor.putString("kEySquare", jsonSquare);
editor.commit();
}
Method For Retrieving That Object.
public void openString() {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
Gson gson = new Gson();
String jsonSquare=sharedPrefs.getString("kEySquare",null);
Type typeSquare = new TypeToken<HashSet<images>>(){}.getType();
HashSet<images> arrayListSquare = gson.fromJson(jsonSquare,typeSquare);`//getting Exception here jsonSyntax Error`
if (arrayListSquare != null) {
img = arrayListSquare;
}
}
As per your comment your json as follows is not in format so that Gson can parse it as you are receiving your circle attribute in string not as json.
{
"img": "[Circle[218.69626, 475.58936, 0,android.graphics.Bitmap#42e13c70,0.0,0.0,0.0,0.0,0.0,0.0,]‌​, Circle[186.74065, 670.43713, 0,android.graphics.Bitmap#42e13c70,0.0,0.0,0.0,0.0,0.0,0.0,]‌​]"
}
So your Json is received as object having only attribute that is img.
and you are parsing it as array. That's error. So contact your back end developer and change json structure accordingly.
You serialise a object and want to deserialise it into a HashSet. That's the problem.
Object spSquare = c.getStringDrawObjImages();
What's the type of spSquare? Suppose it is 'Foo.class', you should deserialise it like this:
Foo foo = gson.fromJson(jsonString, Foo.class);
'foo.img' should be your HashSet

How to convert String value to Custom Model Object in Java?

I have one Model Object. In which, i have multiple values. I want to store this Values in SQLite. But data is large, so i want to store Direct Model object
in databse. So i convert model Object to string and store it into database.
Now, Problem is that how to convert this String value to Model Object.
If you have any idea, please share that with Me.
For example,
Person p = new Person();
p.setname("xyz");
p.setage("18");`
String person=p.toString();
Now How to get this "person" string back to Person "p" model object.
This is my code.
ContentValues values = new ContentValues();
String favorite_id = UUID.randomUUID().toString();
values.put(EMuseumLocalData.KEY_FAVORITE_EXHIBITS_ID, favorite_id);
values.put(EMuseumLocalData.KEY_EXHIBIT_SUBCATEGORY_ITEM_ID, Integer.parseInt(categoryByCustomerList.get(position).getSubCategoryItemID()));
try {
Gson gson = new Gson();
String personString = gson.toJson(getAllCategory.get(position).toString());
values.put(EMuseumLocalData.KEY_EXHIBIT_SUBCATEGORY_ITEM_DATA, personString);
Gson gson1 = new Gson();
CategoryByCustomer categoryByCustomer = gson1.fromJson(personString, categoryByCustomer.getName());
} catch (JSONException e) {
e.printStackTrace();
}
You should use GSON or similar libs for this.
Store to DB
For example If you use GSON
Person p = new Person();
p.setname("xyz");
p.setage("18");
Gson gson = new Gson();
String personString = gson.toJson(p);
Now store this personString to DB.
Read from DB
Get back this object from database, read string from DB and convert it to object like below
String personStringFromDB = READ_LOGIC_OF_DB;
Gson gson = new Gson();
Person p = gson.fromJson(personStringFromDB, Person.class);
For more information, read GSON - Gson Example
Consider using a json string representation of the Model Object. There are many java libraries like Jackson, Gson etc., available to help you with serialization/deserialization part.
Here's a sample code to do this in Jackson
//For conversion of Person object(person) to json String:
String personJsonString = new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(person);
//For conversion of json String back to Person object(person)
Person person = new com.fasterxml.jackson.databind.ObjectMapper().readValue(personJsonString, Person.class);
You can make Model Object serializable. You need to store the serialized object in SQLite. When you need it, you just get that serialized object from SOLite and deserialize it.

How to deserialize a jsonarray into a List<Map> in java using flexjson.deserializer?

In the client side, I have constructed a JSOnARRAY like this:
{"filterEntries":[{"dataName":"mainContact","filterValue":"BILLGATES"}]}.
On the server side (java), I can retireve the values using :
jfilter = JSONValue.parse(jsonFilterStr); //jsonFilterStr={"filterEntries":[{"dataName":"mainContact","filterValue":"BILLGATES"}]}.
JSONArray jFilterEntries = (JSONArray) jfilter.get("filterEntries");
for (int i=0;i<jFilterEntries.size();i++){
JSONObject jFilterEntry = (JSONObject) jFilterEntries.get(i);
String dataName = (String) jFilterEntry.get("dataName");
String filterValue = (String) jFilterEntry.get("filterValue");
}
But the existing app is using flex.json.deserializer and I am unable to achieve the same using flex.json.deserializer. How should I proceed?
I wish to do something like this:
JSONDeserializer jsonDeserializer = new JSONDeserializer();
jsonDeserializer.use(null, List.class);
List<Map<String,String>> lMap= (List<Map<String,String>>)jsonDeserializer.deserialize(params);
Remember the top object that wraps the array. You have to handle that as well. You have to tell it to expect a Map inside the List. To do that you have to specify the type contained in the list by using the path expression "values".
Map<String,List<Map<String,String>>> result = new JSONDeserializer<Map<String,List<Map<String,String>>>>()
.use("values",List.class)
.use("values.values", Map.class)
.deserialize( json);
List<Map<String,String>> filterEntries = result.get("filterEntries");
Updated: Add the new keyword, and made the generic types on the right match the left.

Categories