Ich habe eines ArrayList
von Objekten, die einen Namen und einen Symbolzeiger haben, und ich möchte es in speichern SharedPreferences
. Wie kann ich?
HINWEIS: Ich möchte die Datenbank nicht verwenden
Antworten:
Also von der Android-Entwicklerseite auf Datenspeicher :
Nutzerpreferenzen
Gemeinsame Einstellungen dienen nicht ausschließlich zum Speichern von "Benutzereinstellungen", z. B. dem von einem Benutzer ausgewählten Klingelton. Wenn Sie Benutzereinstellungen für Ihre Anwendung erstellen möchten, lesen Sie PreferenceActivity. Dort finden Sie ein Aktivitätsframework, mit dem Sie Benutzereinstellungen erstellen können, die automatisch beibehalten werden (unter Verwendung gemeinsamer Einstellungen).
Ich denke, es ist in Ordnung, da einfach nur Schlüssel-Wert-Paare bestehen bleiben.
Für das Originalplakat ist das nicht so schwer. Sie durchlaufen einfach Ihre Array-Liste und fügen die Elemente hinzu. In diesem Beispiel verwende ich der Einfachheit halber eine Karte, aber Sie können eine Array-Liste verwenden und sie entsprechend ändern:
// my list of names, icon locations
Map<String, String> nameIcons = new HashMap<String, String>();
nameIcons.put("Noel", "/location/to/noel/icon.png");
nameIcons.put("Bob", "another/location/to/bob/icon.png");
nameIcons.put("another name", "last/location/icon.png");
SharedPreferences keyValues = getContext().getSharedPreferences("name_icons_list", Context.MODE_PRIVATE);
SharedPreferences.Editor keyValuesEditor = keyValues.edit();
for (String s : nameIcons.keySet()) {
// use the name as the key, and the icon as the value
keyValuesEditor.putString(s, nameIcons.get(s));
}
keyValuesEditor.commit()
Sie würden etwas Ähnliches tun, um die Schlüssel-Wert-Paare erneut zu lesen. Lassen Sie mich wissen, ob dies funktioniert.
Update: Wenn Sie API Level 11 oder höher verwenden, gibt es eine Methode zum Schreiben eines String-Sets
Überprüfen Sie unabhängig von der API-Ebene String-Arrays und Objekt-Arrays in SharedPreferences
ARRAY SPEICHERN
public boolean saveArray(String[] array, String arrayName, Context mContext) {
SharedPreferences prefs = mContext.getSharedPreferences("preferencename", 0);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(arrayName +"_size", array.length);
for(int i=0;i<array.length;i++)
editor.putString(arrayName + "_" + i, array[i]);
return editor.commit();
}
LADEN SIE ARRAY
public String[] loadArray(String arrayName, Context mContext) {
SharedPreferences prefs = mContext.getSharedPreferences("preferencename", 0);
int size = prefs.getInt(arrayName + "_size", 0);
String array[] = new String[size];
for(int i=0;i<size;i++)
array[i] = prefs.getString(arrayName + "_" + i, null);
return array;
}
Schreiben,
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
JSONArray jsonArray = new JSONArray();
jsonArray.put(1);
jsonArray.put(2);
Editor editor = prefs.edit();
editor.putString("key", jsonArray.toString());
System.out.println(jsonArray.toString());
editor.commit();
Lesen,
try {
JSONArray jsonArray2 = new JSONArray(prefs.getString("key", "[]"));
for (int i = 0; i < jsonArray2.length(); i++) {
Log.d("your JSON Array", jsonArray2.getInt(i)+"");
}
} catch (Exception e) {
e.printStackTrace();
}
Gemeinsame Einstellungen haben a getStringSet
und putStringSet
Methoden in API Level 11 eingeführt, dies ist jedoch nicht kompatibel mit älteren Android-Versionen (die immer noch beliebt sind) und ist auch auf Sätze von Zeichenfolgen beschränkt.
Android bietet keine besseren Methoden, und das Durchlaufen von Karten und Arrays zum Speichern und Laden ist nicht sehr einfach und sauber, insbesondere für Arrays. Aber eine bessere Implementierung ist nicht so schwer:
package com.example.utils;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;
import android.content.Context;
import android.content.SharedPreferences;
public class JSONSharedPreferences {
private static final String PREFIX = "json";
public static void saveJSONObject(Context c, String prefName, String key, JSONObject object) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString(JSONSharedPreferences.PREFIX+key, object.toString());
editor.commit();
}
public static void saveJSONArray(Context c, String prefName, String key, JSONArray array) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString(JSONSharedPreferences.PREFIX+key, array.toString());
editor.commit();
}
public static JSONObject loadJSONObject(Context c, String prefName, String key) throws JSONException {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
return new JSONObject(settings.getString(JSONSharedPreferences.PREFIX+key, "{}"));
}
public static JSONArray loadJSONArray(Context c, String prefName, String key) throws JSONException {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
return new JSONArray(settings.getString(JSONSharedPreferences.PREFIX+key, "[]"));
}
public static void remove(Context c, String prefName, String key) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
if (settings.contains(JSONSharedPreferences.PREFIX+key)) {
SharedPreferences.Editor editor = settings.edit();
editor.remove(JSONSharedPreferences.PREFIX+key);
editor.commit();
}
}
}
Mit diesen fünf Methoden können Sie jetzt jede Sammlung in freigegebenen Einstellungen speichern. Arbeiten mit JSONObject
und JSONArray
ist sehr einfach. Sie können mit JSONArray (Collection copyFrom)
öffentlichem Konstruktor ein , um JSONArray
aus jeder Java - Sammlung und Verwendung JSONArray
‚s get
Methoden , um die Elemente zuzugreifen.
Es gibt keine Größenbeschränkung für freigegebene Einstellungen (außer den Speicherbeschränkungen des Geräts), sodass diese Methoden in den meisten Fällen funktionieren können, in denen Sie eine schnelle und einfache Speicherung für eine Sammlung in Ihrer App wünschen. Hier findet jedoch eine JSON-Analyse statt, und die Einstellungen in Android werden intern als XML-Dateien gespeichert. Daher empfehle ich die Verwendung anderer persistenter Datenspeichermechanismen, wenn Sie mit Megabyte an Daten arbeiten.
Einfacher Modus für die Speicherung komplexer Objekte mit der Gson Google Library [1]
public static void setComplexObject(Context ctx, ComplexObject obj){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("COMPLEX_OBJECT",new Gson().toJson(obj));
editor.commit();
}
public static ComplexObject getComplexObject (Context ctx){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
String sobj = preferences.getString("COMPLEX_OBJECT", "");
if(sobj.equals(""))return null;
else return new Gson().fromJson(sobj, ComplexObject.class);
}
Ich habe eine Reihe von Taillengrößen (die bereits in meiner Datei array.xml erstellt wurden) mit dem folgenden Code in meine Datei settings.xml geladen. @ array / pant_inch_size ist die ID des gesamten Arrays.
<ListPreference
android:title="choosepantsize"
android:summary="Choose Pant Size"
android:key="pantSizePref"
android:defaultValue="34"
android:entries="@array/pant_inch_size"
android:entryValues="@array/pant_inch_size" />
Dadurch wurde das Menü mit Auswahlmöglichkeiten aus dem Array gefüllt. Ich habe die Standardgröße auf 34 festgelegt. Wenn das Menü angezeigt wird, wird Größe 34 vorausgewählt.
Die einfache Möglichkeit besteht darin, sie wie im folgenden Beispiel in einen JSON-String zu konvertieren:
Gson gson = new Gson();
String json = gson.toJson(myObj);
Speichern Sie dann die Zeichenfolge in den freigegebenen Einstellungen. Sobald Sie es benötigen, rufen Sie einfach eine Zeichenfolge aus den freigegebenen Einstellungen ab und konvertieren Sie sie zurück in JSONArray oder JSONObject (gemäß Ihren Anforderungen).
Zum Schreiben:
private <T> void storeData(String key, T data) {
ByteArrayOutputStream serializedData = new ByteArrayOutputStream();
try {
ObjectOutputStream serializer = new ObjectOutputStream(serializedData);
serializer.writeObject(data);
} catch (IOException e) {
e.printStackTrace();
}
SharedPreferences sharedPreferences = getSharedPreferences(TAG, 0);
SharedPreferences.Editor edit = sharedPreferences.edit();
edit.putString(key, Base64.encodeToString(serializedData.toByteArray(), Base64.DEFAULT));
edit.commit();
}
Zum Lesen:
private <T> T getStoredData(String key) {
SharedPreferences sharedPreferences = getSharedPreferences(TAG, 0);
String serializedData = sharedPreferences.getString(key, null);
T storedData = null;
try {
ByteArrayInputStream input = new ByteArrayInputStream(Base64.decode(serializedData, Base64.DEFAULT));
ObjectInputStream inputStream = new ObjectInputStream(input);
storedData = (T)inputStream.readObject();
} catch (IOException|ClassNotFoundException|java.lang.IllegalArgumentException e) {
e.printStackTrace();
}
return storedData;
}
Dies ist der Code für gemeinsame Einstellungen, den ich erfolgreich verwende. Siehe diesen Link :
public class MainActivity extends Activity {
private static final int RESULT_SETTINGS = 1;
Button button;
public String a="dd";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
button = (Button) findViewById(R.id.btnoptions);
setContentView(R.layout.activity_main);
// showUserSettings();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.settings, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_settings:
Intent i = new Intent(this, UserSettingActivity.class);
startActivityForResult(i, RESULT_SETTINGS);
break;
}
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case RESULT_SETTINGS:
showUserSettings();
break;
}
}
private void showUserSettings() {
SharedPreferences sharedPrefs = PreferenceManager
.getDefaultSharedPreferences(this);
StringBuilder builder = new StringBuilder();
builder.append("\n Pet: "
+ sharedPrefs.getString("prefpetname", "NULL"));
builder.append("\n Address:"
+ sharedPrefs.getString("prefaddress","NULL" ));
builder.append("\n Your name: "
+ sharedPrefs.getString("prefname", "NULL"));
TextView settingsTextView = (TextView) findViewById(R.id.textUserSettings);
settingsTextView.setText(builder.toString());
}
}
GLÜCKLICHE CODIERUNG!
Sie können putStringSet verwenden
Auf diese Weise können Sie ein HashSet wie folgt in Ihren Einstellungen speichern:
sparen
Set<String> values;
SharedPreferences sharedPref =
mContext.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
Editor editor = sharedPref.edit();
editor.putStringSet("YOUR_KEY", values);
editor.apply();
Wiederholen
SharedPreferences sharedPref =
mContext.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
Editor editor = sharedPref.edit();
Set<String> newList = editor.getStringSet("YOUR_KEY", null);
Das putStringSet erlaubt nur ein Set und dies ist eine ungeordnete Liste.
Als ich damit abgehört wurde, bekam ich die Serialisierungslösung, mit der Sie Ihre Zeichenfolge serialisieren können. Aber ich habe mir auch einen Hack ausgedacht.
Lesen Sie dies nur, wenn Sie nichts über Serialisierung gelesen haben. Andernfalls lesen Sie meinen Hack
Um Array-Elemente in der richtigen Reihenfolge zu speichern, können wir das Array in eine einzelne Zeichenfolge serialisieren (indem wir eine neue Klasse ObjectSerializer erstellen (kopieren Sie den Code von - www.androiddevcourse.com/objectserializer.html, ersetzen Sie alles außer dem Paketnamen).
Eingabe von Daten in gemeinsame Einstellungen:
der Rest des Codes in Zeile 38 -
Setzen Sie das nächste Argument wie folgt ein, damit, wenn Daten nicht abgerufen werden, ein leeres Array zurückgegeben wird (wir können keine leere Zeichenfolge setzen, da der Container / die Variable ein Array ist, das keine Zeichenfolge ist).
Kommen zu meinem Hack: -
Führen Sie den Inhalt des Arrays zu einer einzelnen Zeichenfolge zusammen, indem Sie zwischen den einzelnen Elementen ein Symbol einfügen, und teilen Sie es dann beim Abrufen mit diesem Symbol auf. Das Hinzufügen und Abrufen von Zeichenfolgen ist mit gemeinsamen Einstellungen einfach. Wenn Sie sich Sorgen um das Teilen machen, schauen Sie einfach nach "Teilen eines Strings in Java".
[Hinweis: Dies funktioniert einwandfrei, wenn der Inhalt Ihres Arrays primitiver Art ist, z. B. Zeichenfolge, Int, Float usw. Es funktioniert für komplexe Arrays, die eine eigene Struktur haben, beispielsweise ein Telefonbuch, aber das Zusammenführen und Aufteilen wird zu einem etwas komplex. ]]
PS: Ich bin neu in Android, also weiß ich nicht, ob es ein guter Hack ist, also lass mich wissen, ob du bessere Hacks findest.