Як зберегти 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
Кшиштоф Скжинецький,

З якого часу 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();
}

2
як отримати хеш-карту з gson, я отримав повідомлення про помилку, як com.qb.gson.JsonSyntaxException: java.lang.IllegalStateException: очікувалося BEGIN_OBJECT, але було BEGIN_ARRAY у рядку 1, стовпець 2 -
Рам

Очікуваний BEGIN_OBJECT, але був BEGIN_ARRAY, відбувається, тому що HashMap <String, String> повинен бути HashMap <String, Object>, якщо значення завжди є String object, у вас не буде проблем, але якщо значення якогось ключа різниться, то String (наприклад користувальницький об'єкт, або список чи масив), тоді буде викинуто виняток. Отже, щоб мати можливість проаналізувати все, що потрібно, HashMap <рядок, об'єкт>
Стойчо Андрєєв

43

Я написав простий шматок коду, щоб зберегти карту в уподобанні та завантажити карту з уподобань. Не потрібні функції 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 і встановіть контекст як змінну-учасника та використовуйте його відповідно
Vinoj John Hosan

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

але мені потрібно зберегти хеш-карту як саму, як ми додаємо вектор у спільні налаштування
jibysthomas

ніж вам доведеться скористатися серіалізацією та зберегти серіалізовану HashMap у SharedPrefs. Ви можете легко знайти приклади коду, як це зробити.
hovanessyan

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?
Kyle Falconer

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

Використання PowerPreference .

Зберегти дані

HashMap<String, Object> hashMap = new HashMap<String, Object>();
PowerPreference.getDefaultFile().put("key",hashMap);

Зчитування даних

HashMap<String, Object> value = PowerPreference.getDefaultFile().getMap("key", HashMap.class, String.class, Object.class);

1

map -> рядок

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

Ви можете використовувати це у виділеному спільному файлі prefs (джерело: https://developer.android.com/reference/android/content/SharedPreferences.html ):

getAll

додано в 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.


0

Я знаю, що це занадто пізно, але я сподіваюся, це може бути корисним для будь-якого читання ..

так що я роблю це

1) Створіть HashMapand додайте такі дані, як: -

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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.