jibysthomas
jibysthomas

Reputation: 1621

How to save HashMap to Shared Preferences?

How can I save a HashMap Object into Shared Preferences in Android?

Upvotes: 109

Views: 105880

Answers (12)

us_david
us_david

Reputation: 4917

You don't need to save HashMap to file as someone else suggested. It's very well easy to save a HashMap and to SharedPreference and load it from SharedPreference when needed. Here is how:
Assuming you have a

class T

and your hash map is:

HashMap<String, T>

which is saved after being converted to string like this:

       SharedPreferences sharedPref = getSharedPreferences(
            "MyPreference", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.putString("MyHashMap", new Gson().toJson(mUsageStatsMap));
    editor.apply();

where mUsageStatsMap is defined as:

HashMap<String, T>
 

The following code will read the hash map from saved shared preference and correctly load back into mUsageStatsMap:

Gson gson = new Gson();
String json = sharedPref.getString("MyHashMap", "");
Type typeMyType = new TypeToken<HashMap<String, UsageStats>>(){}.getType();
HashMap<String, UsageStats> usageStatsMap = gson.fromJson(json, typeMyType);
mUsageStatsMap = usageStatsMap;  

The key is in Type typeMyType which is used in * gson.fromJson(json, typeMyType)* call. It made it possible to load the hash map instance correctly in Java.

Edit: As suggested by @Makari Kevin, I would also like to point out that the above method requires a dependency on google's gson: 'com.google.code.gson:gson:version_number'

Upvotes: 1

Vinoj John Hosan
Vinoj John Hosan

Reputation: 6873

private void saveMap(Map<String,Boolean> inputMap) {
    SharedPreferences pSharedPref = getApplicationContext().getSharedPreferences("MyVariables", Context.MODE_PRIVATE);
    if (pSharedPref != null){
        JSONObject jsonObject = new JSONObject(inputMap);
        String jsonString = jsonObject.toString();
        pSharedPref.edit()
            .remove("My_map")
            .putString("My_map", jsonString)
            .apply();
    }
}

private Map<String,Boolean> loadMap() {
    Map<String,Boolean> outputMap = new HashMap<>();
    SharedPreferences pSharedPref = getApplicationContext().getSharedPreferences("MyVariables", Context.MODE_PRIVATE);
    try {
        if (pSharedPref != null) {
            String jsonString = pSharedPref.getString("My_map", (new JSONObject()).toString());
            if (jsonString != null) {
                JSONObject jsonObject = new JSONObject(jsonString);
                Iterator<String> keysItr = jsonObject.keys();
                while (keysItr.hasNext()) {
                    String key = keysItr.next();
                    Boolean value = jsonObject.getBoolean(key); 
                    outputMap.put(key, value);
                }
            }
        }
    } catch (JSONException e){
        e.printStackTrace();
    }
    return outputMap;
}

Upvotes: 53

Sos.
Sos.

Reputation: 977

using File Stream

fun saveMap(inputMap: Map<Any, Any>, context: Context) {
    val fos: FileOutputStream = context.openFileOutput("map", Context.MODE_PRIVATE)
    val os = ObjectOutputStream(fos)
    os.writeObject(inputMap)
    os.close()
    fos.close()
}

fun loadMap(context: Context): MutableMap<Any, Any> {
    return try {
        val fos: FileInputStream = context.openFileInput("map")
        val os = ObjectInputStream(fos)
        val map: MutableMap<Any, Any> = os.readObject() as MutableMap<Any, Any>
        os.close()
        fos.close()
        map
    } catch (e: Exception) {
        mutableMapOf()
    }
}

fun deleteMap(context: Context): Boolean {
    val file: File = context.getFileStreamPath("map")
    return file.delete()
}

Usage Example:

var exampleMap: MutableMap<Any, Any> = mutableMapOf()
exampleMap["2"] = 1
saveMap(exampleMap, applicationContext) //save map

exampleMap = loadMap(applicationContext) //load map

Upvotes: 0

ccpizza
ccpizza

Reputation: 31756

The lazy way: storing each key directly in SharedPreferences

For the narrow use case when your map is only gonna have no more than a few dozen elements you can take advantage of the fact that SharedPreferences works pretty much like a map and simply store each entry under its own key:

Storing the map

Map<String, String> map = new HashMap<String, String>();
map.put("color", "red");
map.put("type", "fruit");
map.put("name", "Dinsdale");


SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
// OR use a specific pref name
// context.getSharedPreferences("myMegaMap");

for (Map.Entry<String, String> entry : map.entrySet()) {
    prefs.edit().putString(entry.getKey(), entry.getValue());
}

Reading keys from the map

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
// OR use a specific pref name
// context.getSharedPreferences("myMegaMap");
prefs.getString("color", "pampa");

In case where you use a custom preference name (i.e. context.getSharedPreferences("myMegaMap")) you can also get all keys with prefs.getAll()

Your values can be of any type supported by SharedPreferences: String, int, long, float, boolean.

Upvotes: 1

Evgen But
Evgen But

Reputation: 159

map -> string

val jsonString: String  = Gson().toJson(map)
preferences.edit().putString("KEY_MAP_SAVE", jsonString).apply()

string -> map

val jsonString: String = preferences.getString("KEY_MAP_SAVE", JSONObject().toString())
val listType = object : TypeToken<Map<String, String>>() {}.type
return Gson().fromJson(jsonString, listType)

Upvotes: 9

user11022957
user11022957

Reputation:

String converted = new Gson().toJson(map);
SharedPreferences sharedPreferences = getSharedPreferences("sharepref",Context.MODE_PRIVATE);
sharedPreferences.edit().putString("yourkey",converted).commit();

Upvotes: 1

sivi
sivi

Reputation: 11114

You can use this in a dedicated on shared prefs file (source: https://developer.android.com/reference/android/content/SharedPreferences.html):

getAll

added in API level 1 Map getAll () Retrieve all values from the preferences.

Note that you must not modify the collection returned by this method, or alter any of its contents. The consistency of your stored data is not guaranteed if you do.

Returns Map Returns a map containing a list of pairs key/value representing the preferences.

Upvotes: 1

Kyle Falconer
Kyle Falconer

Reputation: 8500

As a spin off of Vinoj John Hosan's answer, I modified the answer to allow for more generic insertions, based on the key of the data, instead of a single key like "My_map".

In my implementation, MyApp is my Application override class, and MyApp.getInstance() acts to return the context.

public static final String USERDATA = "MyVariables";

private static void saveMap(String key, Map<String,String> inputMap){
    SharedPreferences pSharedPref = MyApp.getInstance().getSharedPreferences(USERDATA, Context.MODE_PRIVATE);
    if (pSharedPref != null){
        JSONObject jsonObject = new JSONObject(inputMap);
        String jsonString = jsonObject.toString();
        SharedPreferences.Editor editor = pSharedPref.edit();
        editor.remove(key).commit();
        editor.putString(key, jsonString);
        editor.commit();
    }
}

private static Map<String,String> loadMap(String key){
    Map<String,String> outputMap = new HashMap<String,String>();
    SharedPreferences pSharedPref = MyApp.getInstance().getSharedPreferences(USERDATA, Context.MODE_PRIVATE);
    try{
        if (pSharedPref != null){
            String jsonString = pSharedPref.getString(key, (new JSONObject()).toString());
            JSONObject jsonObject = new JSONObject(jsonString);
            Iterator<String> keysItr = jsonObject.keys();
            while(keysItr.hasNext()) {
                String k = keysItr.next();
                String v = (String) jsonObject.get(k);
                outputMap.put(k,v);
            }
        }
    }catch(Exception e){
        e.printStackTrace();
    }
    return outputMap;
}

Upvotes: 12

Jonas Borggren
Jonas Borggren

Reputation: 2656

You could try using JSON instead.

For saving

try {
    HashMap<Integer, String> hash = new HashMap<>();
    JSONArray arr = new JSONArray();
    for(Integer index : hash.keySet()) {
        JSONObject json = new JSONObject();
        json.put("id", index);
        json.put("name", hash.get(index));
        arr.put(json);
    }
    getSharedPreferences(INSERT_YOUR_PREF).edit().putString("savedData", arr.toString()).apply();
} catch (JSONException exception) {
    // Do something with exception
}

For getting

try {
    String data = getSharedPreferences(INSERT_YOUR_PREF).getString("savedData");
    HashMap<Integer, String> hash = new HashMap<>();
    JSONArray arr = new JSONArray(data);
    for(int i = 0; i < arr.length(); i++) {
        JSONObject json = arr.getJSONObject(i);
        hash.put(json.getInt("id"), json.getString("name"));
    }
} catch (Exception e) {
    e.printStackTrace();
}

Upvotes: 2

penduDev
penduDev

Reputation: 4785

I use Gson to convert HashMap to String and then save it to SharedPrefs

private void hashmaptest()
{
    //create test hashmap
    HashMap<String, String> testHashMap = new HashMap<String, String>();
    testHashMap.put("key1", "value1");
    testHashMap.put("key2", "value2");

    //convert to string using gson
    Gson gson = new Gson();
    String hashMapString = gson.toJson(testHashMap);

    //save in shared prefs
    SharedPreferences prefs = getSharedPreferences("test", MODE_PRIVATE);
    prefs.edit().putString("hashString", hashMapString).apply();

    //get from shared prefs
    String storedHashMapString = prefs.getString("hashString", "oopsDintWork");
    java.lang.reflect.Type type = new TypeToken<HashMap<String, String>>(){}.getType();
    HashMap<String, String> testHashMap2 = gson.fromJson(storedHashMapString, type);

    //use values
    String toastString = testHashMap2.get("key1") + " | " + testHashMap2.get("key2");
    Toast.makeText(this, toastString, Toast.LENGTH_LONG).show();
}

Upvotes: 99

hovanessyan
hovanessyan

Reputation: 31463

Map<String, String> aMap = new HashMap<String, String>();
aMap.put("key1", "val1");
aMap.put("key2", "val2");
aMap.put("Key3", "val3");

SharedPreferences keyValues = getContext().getSharedPreferences("Your_Shared_Prefs"), Context.MODE_PRIVATE);
SharedPreferences.Editor keyValuesEditor = keyValues.edit();

for (String s : aMap.keySet()) {
    keyValuesEditor.putString(s, aMap.get(s));
}

keyValuesEditor.commit();

Upvotes: 32

Kirill Rakhman
Kirill Rakhman

Reputation: 43841

I would not recommend writing complex objects into SharedPreference. Instead I would use ObjectOutputStream to write it to the internal memory.

File file = new File(getDir("data", MODE_PRIVATE), "map");    
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeObject(map);
outputStream.flush();
outputStream.close();

Upvotes: 87

Related Questions