2014-01-28 14 views
9

Ich muss Set in SharedPreference setzen, aber ich habe ein Problem.SharedPreferences putStringSet funktioniert nicht

wenn ich Schaltfläche klicken, werde ich von SharedPreference Set erhalten und Daten fügen Sie dann auf Set SharedPreference setzen, aber wenn wir Projekt zerstören und es wieder öffnen, die sharedPreference bekommt nur eine Saite in Set

SharedPreferences s = getSharedPreferences("db", 0); 
Log.i("chauster", "1.set = "+s.getStringSet("set", new HashSet<String>())); 

Button btn = (Button)findViewById(R.id.button1); 
btn.setOnClickListener(new Button.OnClickListener() { 

    @Override 
    public void onClick(View v) { 
     SharedPreferences ss = getSharedPreferences("db", 0); 
     Set<String> hs = ss.getStringSet("set", new HashSet<String>()); 
     hs.add(String.valueOf(hs.size()+1)); 
     Editor edit = ss.edit(); 
     edit.putStringSet("set", hs); 
     edit.commit(); 
     SharedPreferences sss = getSharedPreferences("db", 0); 
     Log.i("chauster", "2.set = "+sss.getStringSet("set", 
       new HashSet<String>())); 
    } 
}); 

wenn ich Projekt zuerst installieren, und I-Taste 4-mal klicken, drucken die logcat es

1.set = [] 
2.set = [1] 
2.set = [2, 1] 
2.set = [3, 2, 1] 
2.set = [3, 2, 1, 4] 

es wie Erfolg aussieht String in sharedPreference Set zu setzen, aber wenn ich App zerstören und es wieder öffnen, drucken die logcat es

es bedeutet nur eine Zeichenfolge in Set von sharedPreference, ich weiß nicht, was passiert ist? Bitte helfen Sie mir. Dank ~

+0

Vielleicht sollten Sie meine Antwort akzeptieren, wie die akzeptierte ist falsch –

Antwort

10

Verwendung edit.clear() vor putStringSet

SharedPreferences ss = getSharedPreferences("db", 0); 
Set<String> hs = ss.getStringSet("set", new HashSet<String>()); 
hs.add(String.valueOf(hs.size()+1)); 
Editor edit = ss.edit(); 
edit.clear(); 
edit.putStringSet("set", hs); 
edit.commit(); 
+2

warum es nicht ohne klare Arbeit ... hat der gleiche Schlüssel ein Problem? – henry4343

+14

Dies ist keine Lösung ... clear() löscht alle Einstellungen! –

+3

Dies würde _all_ Einstellungen löschen, stattdessen mit der Taste entfernen - 'edit.remove ('set')'. Dies wird jedoch vermieden, indem ein neuer Satz aus demjenigen erzeugt wird, der von pref zurückgegeben wird, wie zum Beispiel 'Set new = new HashSet <> (ss.getStringSet ('set', neuer HashSet ()));' – Tapirboy

-1

Leute, ich bin hier aus historischen Gründen zu halten. Verwenden Sie diesen Ansatz nicht! (Was nutzt es? Es zeigt, wie schlecht Code erscheint: die API verhält sich counter-intuitiv, es gibt ein Problem, ein Entwickler versucht, um die GOTCHA zu umgehen. Schlechter Code erscheint. Später wird die GOTCHA offiziell dokumentiert, und eine andere Abhilfe wird vorgeschlagen, aber die schlechten Code wird geteilt.)


Versuchen Sie, speichern SharedPreferences zu einer statischen variablen statt getSharedPreferences jedes Mal aufgerufen wird. Das hört sich furchtbar an, aber das hat einmal für mich funktioniert.

public class Prefs { 
    // this singleton is a workaround for an Android bug: 
    // two SharedPreferences objects do not see changes in each other. 
    private static SharedPreferences theSingletone; 
    public static SharedPreferences get(Activity from) { 
     //PreferenceManager.getDefaultSharedPreferences(getContext()); 
     if (theSingletone == null) { 
      theSingletone = from.getApplicationContext().getSharedPreferences("prefs", Context.MODE_PRIVATE); 
     } 
     return theSingletone; 
    } 
} 
2

Remove der Schlüssel für HashSet in SharedPreferences, commit dann neuen Wert hinzuzufügen.

SharedPreferences ss; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_third); 
    ss = getSharedPreferences("db", 0); 
    fun(); 
} 

void fun() { 
    Log.i("chauster", "1.set = "+ss.getStringSet("set", new HashSet<String>())); 

    Button btn = (Button)findViewById(R.id.btn); 
    btn.setOnClickListener(new Button.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      Set<String> hs = ss.getStringSet("set", new HashSet<String>()); 
      hs.add(String.valueOf(hs.size()+1)); 
      Log.i(TAG, "list: " + hs.toString()); 
      Editor edit = ss.edit(); 
      edit.remove("set"); 
      edit.commit(); 
      edit.putStringSet("set", hs); 
      Log.i(TAG, "saved: " + edit.commit()); 

      Log.i("chauster", "2.set = "+ss.getStringSet("set", new HashSet<String>())); 
     } 
    }); 
} 
27

Sie fielen in die übliche Falle der Bearbeitung des Wertes, den Sie von getStringSet() erhalten haben. Dies ist verboten in the docs

Sie sollten:

SharedPreferences ss = getSharedPreferences("db", 0); 
Set<String> hs = ss.getStringSet("set", new HashSet<String>()); 
Set<String> in = new HashSet<String>(hs); 
in.add(String.valueOf(hs.size()+1)); 
ss.edit().putStringSet("set", in).commit(); // brevity 
// SharedPreferences sss = getSharedPreferences("db", 0); // not needed 
Log.i("chauster", "2.set = "+ ss.getStringSet("set", new HashSet<String>())); 

Für eine halbe gebackene Erklärung siehe: Misbehavior when trying to store a string set using SharedPreferences

+2

das ist die richtige Antwort –

+0

Vielen Dank, dass Sie dies mit einem Hinweis auf die Erklärung geschrieben haben! – BVB