Как сохранить HashMap в общих настройках?

Ответы:

84

Я бы не рекомендовал писать сложные объекты в SharedPreference. Вместо этого я бы использовал ObjectOutputStreamдля записи во внутреннюю память.

File file = new File(getDir("data", MODE_PRIVATE), "map");    
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeObject(map);
outputStream.flush();
outputStream.close();
Кирилл Рахман
источник
6
С помощью ObjectInputStream.
Кирилл Рахман
5
вот пример совместного использования ObjectOutputStream и ObjectInputStream: tutorialspoint.com/java/io/objectinputstream_readobject.htm
Krzysztof Skrzynecki
С каких это пор Hashmap - сложный объект? Как вы это предположили?
Педро Пауло Аморим,
78

Я использую Gsonдля преобразования HashMapв, Stringа затем сохраняю в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();
}
penduDev
источник
2
как получить хэш-карту из gson, я получил сообщение об ошибке, например com.qb.gson.JsonSyntaxException: java.lang.IllegalStateException: ожидалось BEGIN_OBJECT, но было BEGIN_ARRAY в строке 1, столбец 2 -
Ram
Ожидается BEGIN_OBJECT, но был BEGIN_ARRAY, потому что HashMap <String, String> должен быть HashMap <String, Object>, если значения всегда являются объектом String, у вас не будет никаких проблем, но если значение некоторого ключа является diff, тогда String (например настраиваемый объект, список или массив), тогда будет сгенерировано исключение. Чтобы иметь возможность разобрать все, что вам нужно, HashMap <String, Object>
Стойчо Андреев
44

Я написал простой фрагмент кода, чтобы сохранить карту в предпочтении и загрузить карту из предпочтения. Никаких функций GSON или Jackson не требуется. Я просто использовал карту с String в качестве ключа и Boolean в качестве значения.

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();
    Editor editor = pSharedPref.edit();
    editor.remove("My_map").commit();
    editor.putString("My_map", jsonString);
    editor.commit();
  }
}

private Map<String,Boolean> loadMap(){
  Map<String,Boolean> outputMap = new HashMap<String,Boolean>();
  SharedPreferences pSharedPref = getApplicationContext().getSharedPreferences("MyVariables", Context.MODE_PRIVATE);
  try{
    if (pSharedPref != null){       
      String jsonString = pSharedPref.getString("My_map", (new JSONObject()).toString());
      JSONObject jsonObject = new JSONObject(jsonString);
      Iterator<String> keysItr = jsonObject.keys();
      while(keysItr.hasNext()) {
        String key = keysItr.next();
        Boolean value = (Boolean) jsonObject.get(key);
        outputMap.put(key, value);
      }
    }
  }catch(Exception e){
    e.printStackTrace();
  }
  return outputMap;
}
Винодж Джон Хосан
источник
идеальный ответ :)
Рамкеш Ядав
Как я могу получить доступ getApplicationContextиз простого класса?
Дмитрий
@Dmitry Ярлык: в вашем простом классе включите метод set context, установите контекст как переменную-член и используйте его соответственно
Винодж Джон Хосан,
32
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();
Хованесян
источник
но мне нужно сохранить хеш-карту как
таковую,
чем вам, вероятно, придется использовать сериализацию и сохранить сериализованную HashMap в SharedPrefs. Вы можете легко найти примеры кода, как это сделать.
Хованесян
11

В качестве дополнения к ответу Виноджа Джона Хосана я изменил ответ, чтобы обеспечить более общие вставки на основе ключа данных, а не одного ключа, например "My_map".

В моей реализации MyAppэто мой Applicationкласс переопределения, MyApp.getInstance()который возвращает 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;
}
Кайл Фалконер
источник
Как я могу получить доступ к MyApp из библиотеки?
Дмитрий
@Dmitry Вы должны сделать это так же, как если бы вы обращались к Contextэкземпляру из библиотеки. Ознакомьтесь с другим вопросом SO: возможно ли получить контекст приложения в проекте библиотеки Android?
Кайл Фалконер
2

Вместо этого вы можете попробовать использовать JSON.

Для экономии

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
}

Для получения

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();
}
Йонас Борггрен
источник
1
String converted = new Gson().toJson(map);
SharedPreferences sharedPreferences = getSharedPreferences("sharepref",Context.MODE_PRIVATE);
sharedPreferences.edit().putString("yourkey",converted).commit();

источник
1
Как вернуть на карту?
زياد
1

карта -> строка

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

строка -> карта

val jsonString: String = preferences.getString("KEY_MAP_SAVE", JSONObject().toString())
val listType = object : TypeToken<Map<String, String>>() {}.type
return Gson().fromJson(jsonString, listType)
Евгений Бут
источник
0

Вы можете использовать это в специальном файле общих настроек (источник: https://developer.android.com/reference/android/content/SharedPreferences.html ):

получить все

добавлено в API уровня 1. Карта getAll () Получить все значения из настроек.

Обратите внимание, что вы не должны изменять коллекцию, возвращаемую этим методом, или изменять какое-либо ее содержимое. Если вы это сделаете, целостность ваших сохраненных данных не гарантируется.

Возвращает карту. Возвращает карту, содержащую список пар ключ / значение, представляющих предпочтения.

сиви
источник
0

Ленивый способ: хранить каждый ключ прямо в SharedPreferences

Для узкого случая использования, когда ваша карта будет иметь не более нескольких десятков элементов, вы можете воспользоваться тем фактом, что SharedPreferences работает во многом как карта и просто хранит каждую запись под собственным ключом:

Хранение карты

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());
}

Чтение ключей с карты

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

В случае, если вы используете собственное имя предпочтения (т.е. context.getSharedPreferences("myMegaMap")), вы также можете получить все ключи с помощьюprefs.getAll()

Ваши значения могут быть любого типа , поддерживаемого SharedPreferences: String, int, long, float, boolean.

ccpizza
источник
-2

Я знаю, что уже слишком поздно, но я надеюсь, что это может быть полезно для любого чтения.

так что я делаю

1) Создайте HashMap и добавьте такие данные, как: -

HashMap hashmapobj = new HashMap();
  hashmapobj.put(1001, "I");
  hashmapobj.put(1002, "Love");
  hashmapobj.put(1003, "Java");

2) Напишите это в редактор shareprefrences, например: -

SharedPreferences sharedpreferences = getSharedPreferences(MyPREFERENCES,Context.MODE_PRIVATE);
    Editor editor = sharedpreferences.edit();
    editor.putStringSet("key", hashmapobj );
    editor.apply(); //Note: use commit if u wan to receive response from shp

3) Чтение таких данных, как: - в новом классе, где вы хотите, чтобы они были прочитаны

   HashMap hashmapobj_RECIVE = new HashMap();
     SharedPreferences sharedPreferences (MyPREFERENCES,Context.MODE_PRIVATE;
     //reading HashMap  from sharedPreferences to new empty HashMap  object
     hashmapobj_RECIVE = sharedpreferences.getStringSet("key", null);
TPX
источник
Карта не набор
Solidogen