Is it possible to add an array or object to SharedPreferences on Android
Solution 1
So from the android developer site on Data Storage:
User Preferences
Shared preferences are not strictly for saving "user preferences," such as what ringtone a user has chosen. If you're interested in creating user preferences for your application, see PreferenceActivity, which provides an Activity framework for you to create user preferences, which will be automatically persisted (using shared preferences).
So I think it is okay since it is simply just key-value pairs which are persisted.
To the original poster, this is not that hard. You simply just iterate through your array list and add the items. In this example I use a map for simplicity but you can use an array list and change it appropriately:
// my list of names, icon locations
Map<String, String> nameIcons = new HashMap<String, String>();
nameIcons.put("Noel", "/location/to/noel/icon.png");
nameIcons.put("Bob", "another/location/to/bob/icon.png");
nameIcons.put("another name", "last/location/icon.png");
SharedPreferences keyValues = getContext().getSharedPreferences("name_icons_list", Context.MODE_PRIVATE);
SharedPreferences.Editor keyValuesEditor = keyValues.edit();
for (String s : nameIcons.keySet()) {
// use the name as the key, and the icon as the value
keyValuesEditor.putString(s, nameIcons.get(s));
}
keyValuesEditor.commit()
You would do something similar to read the key-value pairs again. Let me know if this works.
Update: If you're using API level 11 or later, there is a method to write out a String Set
Solution 2
Regardless of the API level, Check String arrays and Object arrays in SharedPreferences
SAVE ARRAY
public boolean saveArray(String[] array, String arrayName, Context mContext) {
SharedPreferences prefs = mContext.getSharedPreferences("preferencename", 0);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(arrayName +"_size", array.length);
for(int i=0;i<array.length;i++)
editor.putString(arrayName + "_" + i, array[i]);
return editor.commit();
}
LOAD ARRAY
public String[] loadArray(String arrayName, Context mContext) {
SharedPreferences prefs = mContext.getSharedPreferences("preferencename", 0);
int size = prefs.getInt(arrayName + "_size", 0);
String array[] = new String[size];
for(int i=0;i<size;i++)
array[i] = prefs.getString(arrayName + "_" + i, null);
return array;
}
Solution 3
To write,
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
JSONArray jsonArray = new JSONArray();
jsonArray.put(1);
jsonArray.put(2);
Editor editor = prefs.edit();
editor.putString("key", jsonArray.toString());
System.out.println(jsonArray.toString());
editor.commit();
To Read,
try {
JSONArray jsonArray2 = new JSONArray(prefs.getString("key", "[]"));
for (int i = 0; i < jsonArray2.length(); i++) {
Log.d("your JSON Array", jsonArray2.getInt(i)+"");
}
} catch (Exception e) {
e.printStackTrace();
}
Other way to do same:
//Retrieve the values
Gson gson = new Gson();
String jsonText = Prefs.getString("key", null);
String[] text = gson.fromJson(jsonText, String[].class); //EDIT: gso to gson
//Set the values
Gson gson = new Gson();
List<String> textList = new ArrayList<String>(data);
String jsonText = gson.toJson(textList);
prefsEditor.putString("key", jsonText);
prefsEditor.apply();
Using GSON in Java:
public void saveArrayList(ArrayList<String> list, String key){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor editor = prefs.edit();
Gson gson = new Gson();
String json = gson.toJson(list);
editor.putString(key, json);
editor.apply();
}
public ArrayList<String> getArrayList(String key){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
Gson gson = new Gson();
String json = prefs.getString(key, null);
Type type = new TypeToken<ArrayList<String>>() {}.getType();
return gson.fromJson(json, type);
}
Using GSON in Kotlin
fun saveArrayList(list: java.util.ArrayList<String?>?, key: String?) {
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity)
val editor: Editor = prefs.edit()
val gson = Gson()
val json: String = gson.toJson(list)
editor.putString(key, json)
editor.apply()
}
fun getArrayList(key: String?): java.util.ArrayList<String?>? {
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity)
val gson = Gson()
val json: String = prefs.getString(key, null)
val type: Type = object : TypeToken<java.util.ArrayList<String?>?>() {}.getType()
return gson.fromJson(json, type)
}
Solution 4
Shared preferences introduced a getStringSet
and putStringSet
methods in API Level 11, but that's not compatible with older versions of Android (which are still popular), and also is limited to sets of strings.
Android does not provide better methods, and looping over maps and arrays for saving and loading them is not very easy and clean, specially for arrays. But a better implementation isn't that hard:
package com.example.utils;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;
import android.content.Context;
import android.content.SharedPreferences;
public class JSONSharedPreferences {
private static final String PREFIX = "json";
public static void saveJSONObject(Context c, String prefName, String key, JSONObject object) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString(JSONSharedPreferences.PREFIX+key, object.toString());
editor.commit();
}
public static void saveJSONArray(Context c, String prefName, String key, JSONArray array) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString(JSONSharedPreferences.PREFIX+key, array.toString());
editor.commit();
}
public static JSONObject loadJSONObject(Context c, String prefName, String key) throws JSONException {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
return new JSONObject(settings.getString(JSONSharedPreferences.PREFIX+key, "{}"));
}
public static JSONArray loadJSONArray(Context c, String prefName, String key) throws JSONException {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
return new JSONArray(settings.getString(JSONSharedPreferences.PREFIX+key, "[]"));
}
public static void remove(Context c, String prefName, String key) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
if (settings.contains(JSONSharedPreferences.PREFIX+key)) {
SharedPreferences.Editor editor = settings.edit();
editor.remove(JSONSharedPreferences.PREFIX+key);
editor.commit();
}
}
}
Now you can save any collection in shared preferences with this five methods. Working with JSONObject
and JSONArray
is very easy. You can use JSONArray (Collection copyFrom)
public constructor to make a JSONArray
out of any Java collection and use JSONArray
's get
methods to access the elements.
There is no size limit for shared preferences (besides device's storage limits), so these methods can work for most of usual cases where you want a quick and easy storage for some collection in your app. But JSON parsing happens here, and preferences in Android are stored as XMLs internally, so I recommend using other persistent data store mechanisms when you're dealing with megabytes of data.
Solution 5
Easy mode for complex object storage with using Gson google library [1]
public static void setComplexObject(Context ctx, ComplexObject obj){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("COMPLEX_OBJECT",new Gson().toJson(obj));
editor.commit();
}
public static ComplexObject getComplexObject (Context ctx){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
String sobj = preferences.getString("COMPLEX_OBJECT", "");
if(sobj.equals(""))return null;
else return new Gson().fromJson(sobj, ComplexObject.class);
}
Related videos on Youtube
zsniperx
Updated on February 18, 2021Comments
-
zsniperx over 3 years
I have an
ArrayList
of objects that have a name and an icon pointer and I want to save it inSharedPreferences
. How can I do?NOTE: I don't want to use Database
-
zsniperx over 13 yearsThanks Noel, I figured it out with the help of your code. Watch the code typos though. ;)
-
zsniperx over 13 yearsHi Keith, thank you for your response. I need to store an order and I don't work with preference ui so I don't that your code matches with what I need to accomplish. Thanks anyways
-
Keith over 13 yearsah!! I misinterpreted your question, sorry about that. For any other readers, my XML code simply grabs items from my array.xml file and loaded them up into the preference menu, with the default preference pre-selected as "34" in this instance. I then use java to find the identifier for this particular preference, which is "pantSizePref" (the "key").
-
FeatureCreep about 12 yearsIf you are going with JSON, maybe check out gson: code.google.com/p/google-gson -- it converts java objects to and from JSON.
-
Mostafa about 12 yearsThat would be an interesting combination.
-
Kyle Ivey over 10 yearsThis is a terrible technique. See the comments on that blog: "The problem with this approach is that you'll pollute your preferences. Say, you save an array with 100 entries and then shrink it ito 2. You'll still have 100 entries in your preferences unless you clean it up first."
-
Sherif elKhatib over 10 yearsCleaning up is rather an easy addition
-
Bala Vishnu about 10 yearsWorked like a charm...Thx
-
Renan Franca over 9 yearsThe best one! Mark this as the ANSWER!
-
Martin Pfeffer over 9 yearsThanks, very nice styled code. This is one of my favorite answers here on SO. :)
-
Amir Hossein Ghasemi about 9 yearsThis is a wrong approach!!! you try add 100 variables, and this is terrible!! instead you can use this method with jsonarray and jsonbj : stackoverflow.com/a/8287418/2652368
-
Sherif elKhatib about 9 years@AmirHosseinGhasemi both approaches are actually hacks. thanks
-
androidguy over 7 yearsThis seems like a sound suggestion. The common collections all implement Serializable, and your basic String, Number and Date are Serializable. The only downside would be performance.