Wie speichere ich HashMap in freigegebenen Einstellungen?

Antworten:

84

Ich würde nicht empfehlen, komplexe Objekte in SharedPreference zu schreiben. Stattdessen würde ich es verwenden ObjectOutputStream, um es in den internen Speicher zu schreiben.

File file = new File(getDir("data", MODE_PRIVATE), "map");    
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeObject(map);
outputStream.flush();
outputStream.close();
Kirill Rakhman
quelle
6
Mit einem ObjectInputStream.
Kirill Rakhman
5
Hier ist ein Beispiel, wie ObjectOutputStream und ObjectInputStream zusammen verwendet werden: tutorialspoint.com/java/io/objectinputstream_readobject.htm
Krzysztof Skrzynecki
Seit wann ist Hashmap ein komplexes Objekt? Wie haben Sie das angenommen?
Pedro Paulo Amorim
78

Ich benutze Gsonzu konvertieren HashMapzu Stringund dann speichern Sie es aufSharedPrefs

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
quelle
2
Wie bekomme ich eine Hashmap von Gson? Ich habe eine Fehlermeldung wie com.qb.gson.JsonSyntaxException: java.lang.IllegalStateException: Erwartet BEGIN_OBJECT, war aber BEGIN_ARRAY in Zeile 1 Spalte 2 -
Ram
Erwartetes BEGIN_OBJECT, aber BEGIN_ARRAY passiert, weil HashMap <String, String> HashMap <String, Object> sein sollte. Wenn die Werte immer String-Objekt sind, haben Sie keine Probleme, aber wenn der Wert eines Schlüssels diff ist, dann String (zum Beispiel benutzerdefiniertes Objekt oder Liste oder Array), dann wird eine Ausnahme ausgelöst.
Um also
42

Ich habe einen einfachen Code geschrieben, um die Karte in der Präferenz zu speichern und die Karte aus der Präferenz zu laden. Keine GSON- oder Jackson-Funktionen erforderlich. Ich habe gerade eine Map mit String als Schlüssel und Boolean als Wert verwendet.

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;
}
Vinoj John Hosan
quelle
perfekte Antwort :)
Ramkesh Yadav
Wie kann ich getApplicationContextvon einer einfachen Klasse aus zugreifen ?
Dmitry
@Dmitry Eine Verknüpfung: Fügen Sie in Ihre einfache Klasse set context method ein und legen Sie den Kontext als Mitgliedsvariable fest und verwenden Sie ihn entsprechend
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();
hovanessyan
quelle
aber ich muss die Hash-Karte als sich selbst speichern, wie wir Vektor in die gemeinsamen
Einstellungen
Dann müssen Sie wahrscheinlich die Serialisierung verwenden und die serialisierte HashMap in SharedPrefs speichern. Sie können leicht Codebeispiele finden, wie das geht.
Hovanessyan
11

Als Ableger der Antwort von Vinoj John Hosan habe ich die Antwort geändert, um allgemeinere Einfügungen basierend auf dem Schlüssel der Daten anstelle eines einzelnen Schlüssels wie zu ermöglichen "My_map".

In meiner Implementierung MyAppist meine ApplicationOverride-Klasse und MyApp.getInstance()handelt, um die zurückzugeben 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;
}
Kyle Falconer
quelle
Wie kann ich von einer Bibliothek aus auf MyApp zugreifen?
Dmitry
@Dmitry Sie würden dies genauso tun, wie Sie Contextvon einer Bibliothek aus auf die Instanz zugreifen würden . Schauen Sie sich diese andere SO-Frage an: Ist es möglich, den Anwendungskontext in einem Android-Bibliotheksprojekt abzurufen?
Kyle Falconer
2

Sie können stattdessen versuchen, JSON zu verwenden.

Zum Speichern

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
}

Zum bekommen

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();
}
Jonas Borggren
quelle
1
String converted = new Gson().toJson(map);
SharedPreferences sharedPreferences = getSharedPreferences("sharepref",Context.MODE_PRIVATE);
sharedPreferences.edit().putString("yourkey",converted).commit();

quelle
1
Wie kann ich es an Map zurückgeben?
زياد
1

Verwenden von PowerPreference .

Daten speichern

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

Daten lesen

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

map -> string

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

Zeichenfolge -> Karte

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

Sie können dies in einer dedizierten Datei mit freigegebenen Einstellungen verwenden (Quelle: https://developer.android.com/reference/android/content/SharedPreferences.html ):

Nimm alle

hinzugefügt in API Level 1 Map getAll () Ruft alle Werte aus den Einstellungen ab.

Beachten Sie, dass Sie die von dieser Methode zurückgegebene Sammlung oder deren Inhalt nicht ändern dürfen. Die Konsistenz Ihrer gespeicherten Daten kann in diesem Fall nicht garantiert werden.

Rückgabe der Karte Gibt eine Karte zurück, die eine Liste von Schlüssel- / Wertpaaren enthält, die die Einstellungen darstellen.

sivi
quelle
0

Der faule Weg: Speichern Sie jeden Schlüssel direkt in SharedPreferences

Für den engen Anwendungsfall, in dem Ihre Karte nur ein paar Dutzend Elemente enthält, können Sie die Tatsache nutzen, dass SharedPreferences wie eine Karte funktioniert, und einfach jeden Eintrag unter einem eigenen Schlüssel speichern:

Karte speichern

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

Schlüssel von der Karte lesen

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

Wenn Sie einen benutzerdefinierten Voreinstellungsnamen (dh context.getSharedPreferences("myMegaMap")) verwenden, können Sie auch alle Schlüssel mit abrufenprefs.getAll()

Ihre Werte können von jeder Art von SharedPreferences unterstützt werden: String, int, long, float, boolean.

ccpizza
quelle
0

Ich weiß, dass es etwas zu spät ist, aber ich hoffe, dass dies für jede Lesung hilfreich sein kann.

Also was ich tue ist

1) Erstellen Sie HashMap und fügen Sie Daten hinzu wie: -

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

2) Schreiben Sie es in den Shareprefrences-Editor wie: -

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) Lesen von Daten wie: - in einer neuen Klasse, in der sie gelesen werden sollen

   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
quelle