Speichern und Abrufen eines Klassenobjekts in gemeinsamen Einstellungen

111

Können wir in Android ein Objekt einer Klasse in gemeinsamen Einstellungen speichern und das Objekt später abrufen?

Wenn es möglich ist, wie es geht? Wenn es nicht möglich ist, welche anderen Möglichkeiten gibt es dafür?

Ich weiß, dass Serialisierung eine Option ist, aber ich suche nach Möglichkeiten, die gemeinsame Präferenzen verwenden.

androidGuy
quelle
Ich füge eine Hilfsbibliothek hinzu, falls jemand sie benötigt: github.com/ionull/objectify
Tsung Goh
Hier ist ein Beispiel thegeekyland.blogspot.com/2015/11/…
Arlind
Hier ist eine Antwort auf eine ähnliche Frage.
tpk
Sie können diese Bibliothek verwenden, in der viele Funktionen integriert sind. github.com/moinkhan-in/PreferenceSpider
Moinkhan

Antworten:

15

Nicht möglich.

Sie können nur einfache Werte in SharedPrefences SharePreferences.Editor speichern

Was ist besonders an der Klasse, die Sie speichern müssen?

Blundell
quelle
1
Danke. Ich möchte einige Datenelemente der Klasse speichern. Und ich möchte nicht jeden Wert von Datenelementen mit gemeinsamen Einstellungen speichern. Ich möchte es als Objekt speichern. Wenn keine gemeinsamen Einstellungen vorhanden sind, welche anderen Optionen habe ich?
androidGuy
5
Serialisieren Sie es und speichern Sie es in einer Datenbank (SQLite) / in einer Flatfile.
Blundell
5
Die Antwort ist nicht vollständig. Die mögliche Lösung besteht darin, das Pojo in ByteArrayOutPutStream umzuwandeln und als String in den SharedPreferences zu speichern
rallat
27
Eine andere Option speichert es als json und ordnet es dann wieder zu. Mit GSON oder jackSON ist das ganz einfach
rallat
2
Lassen Sie mich meine Zeitmaschine zurück auf 2011 bringen und das herausfinden
Blundell
324

Ja, wir können dies mit Gson tun

Laden Sie den Arbeitscode von GitHub herunter

SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);

Zum Speichern

Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(myObject); // myObject - instance of MyObject
prefsEditor.putString("MyObject", json);
prefsEditor.commit();

Für bekommen

Gson gson = new Gson();
String json = mPrefs.getString("MyObject", "");
MyObject obj = gson.fromJson(json, MyObject.class);

Update1

Die neueste Version von GSON kann von github.com/google/gson heruntergeladen werden .

Update2

Wenn Sie Gradle / Android Studio verwenden, geben Sie einfach Folgendes in den build.gradleAbschnitt "Abhängigkeiten" ein.

implementation 'com.google.code.gson:gson:2.6.2'
Parag Chauhan
quelle
funktioniert in meinem Fall nicht. Selbst nachdem jar in libs eingefügt und der Build-Pfad festgelegt wurde, wird die Gson-Klasse nicht aufgelöst.
Shirish Herwade
Sauberes Projekt, dann versuchen Sie @ShirishHerwade
Parag Chauhan
@parag das funktioniert auch nicht. Können Sie mir bitte die Schritte mitteilen, mit denen ich dieses Glas verwenden kann, um den obigen Fehler zu beseitigen? Da ich dieses JAR erfolgreich im libs-Ordner und dann im "Java Build Path" hinzugefügt habe, habe ich auch versucht, json extern auf meinem Desktop zu speichern
Shirish Herwade
7
Diese Antwort wäre noch besser, wenn sie auch ihre Grenzen erwähnen würde. Welche Art von Objekt können und können wir auf diese Weise speichern und abrufen? Offensichtlich wird es nicht für alle Klassen funktionieren.
wvdz
3
String json = gson.toJson("MyObject");sollte das Objekt kein String sein.
Ahmed Hegazy
44

Wir können Outputstream verwenden, um unser Objekt in den internen Speicher auszugeben. Und in einen String konvertieren und dann vorzugsweise speichern. Beispielsweise:

    mPrefs = getPreferences(MODE_PRIVATE);
    SharedPreferences.Editor ed = mPrefs.edit();
    ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();

    ObjectOutputStream objectOutput;
    try {
        objectOutput = new ObjectOutputStream(arrayOutputStream);
        objectOutput.writeObject(object);
        byte[] data = arrayOutputStream.toByteArray();
        objectOutput.close();
        arrayOutputStream.close();

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        Base64OutputStream b64 = new Base64OutputStream(out, Base64.DEFAULT);
        b64.write(data);
        b64.close();
        out.close();

        ed.putString(key, new String(out.toByteArray()));

        ed.commit();
    } catch (IOException e) {
        e.printStackTrace();
    }

wenn wir Objekt aus Präferenz extrahieren müssen. Verwenden Sie den folgenden Code

    byte[] bytes = mPrefs.getString(indexName, "{}").getBytes();
    if (bytes.length == 0) {
        return null;
    }
    ByteArrayInputStream byteArray = new ByteArrayInputStream(bytes);
    Base64InputStream base64InputStream = new Base64InputStream(byteArray, Base64.DEFAULT);
    ObjectInputStream in;
    in = new ObjectInputStream(base64InputStream);
    MyObject myObject = (MyObject) in.readObject();
Kislingk
quelle
Hallo, ich weiß, dass dies vor einiger Zeit gepostet wurde, aber sind Sie sicher, dass der Code zum Extrahieren des gespeicherten Objekts korrekt ist? In den letzten beiden Zeilen werden mehrere Fehler angezeigt, die darüber jammern, wie explizite Konstruktoren definiert werden müssen, anstatt einfach "new ObjectInputStream (byteArray)" zu haben. Danke für die Hilfe!
Wakka Wakka Wakka
Hallo, ich bekomme plötzlich eine EOFException für in = new ObjectInputStream (base64InputStream); Ich schreibe es genau so an gemeinsame Einstellungen, wie Sie es tun. Was denkst du könnte falsch sein?
Marienke
Haben Sie eine Ausnahme, wenn Sie Object to pref schreiben? Aus SDK: Ausgelöste EOFException, wenn ein Programm während eines Eingabevorgangs auf das Ende einer Datei oder eines Streams stößt.
Kislingk
Kudos, dies ist die beste Lösung, die ich bisher für dieses Problem gefunden habe. Keine Abhängigkeiten. Es ist jedoch zu beachten, dass das Objekt und alle darin enthaltenen benutzerdefinierten Objekte die Schnittstelle Serializable implementieren müssen, um ObjectOutput / InputStream für ein Objekt verwenden zu können.
user1112789
8

Ich hatte das gleiche Problem, hier ist meine Lösung:

Ich habe die Klassen MyClass und ArrayList <MyClass>, die ich in den freigegebenen Einstellungen speichern möchte. Zuerst habe ich MyClass eine Methode hinzugefügt, die es in ein JSON-Objekt konvertiert:

public JSONObject getJSONObject() {
    JSONObject obj = new JSONObject();
    try {
        obj.put("id", this.id);
        obj.put("name", this.name);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return obj;
}

Dann ist hier die Methode zum Speichern des Objekts "ArrayList <MyClass> -Elemente":

SharedPreferences mPrefs = context.getSharedPreferences("some_name", 0);
    SharedPreferences.Editor editor = mPrefs.edit();

    Set<String> set= new HashSet<String>();
    for (int i = 0; i < items.size(); i++) {
        set.add(items.get(i).getJSONObject().toString());
    }

    editor.putStringSet("some_name", set);
    editor.commit();

Und hier ist die Methode zum Abrufen des Objekts:

public static ArrayList<MyClass> loadFromStorage() {
    SharedPreferences mPrefs = context.getSharedPreferences("some_name", 0);

    ArrayList<MyClass> items = new ArrayList<MyClass>();

    Set<String> set = mPrefs.getStringSet("some_name", null);
    if (set != null) {
        for (String s : set) {
            try {
                JSONObject jsonObject = new JSONObject(s);
                Long id = jsonObject.getLong("id"));
                String name = jsonObject.getString("name");
                MyClass myclass = new MyClass(id, name);

                items.add(myclass);

            } catch (JSONException e) {
                e.printStackTrace();
         }
    }
    return items;
}

Beachten Sie, dass StringSet in den freigegebenen Einstellungen seit API 11 verfügbar ist.

Micer
quelle
Mein Problem gelöst. Ich möchte etwas hinzufügen. Bei der ersten Verwendung müssen wir prüfen, ob die Menge null ist. if (set! = null) {for (String s: set) {..}}
xevser
@xevser Ich habe wie vorgeschlagen null check hinzugefügt. Vielen Dank.
Micer
6

Verwenden der Gson Library:

dependencies {
compile 'com.google.code.gson:gson:2.8.2'
}

Geschäft:

Gson gson = new Gson();
//Your json response object value store in json object
JSONObject jsonObject = response.getJSONObject();
//Convert json object to string
String json = gson.toJson(jsonObject);
//Store in the sharedpreference
getPrefs().setUserJson(json);

Abrufen:

String json = getPrefs().getUserJson();
Ramesh Sambu
quelle
Paket ist kein universeller Serialisierungsmechanismus. Diese Klasse (und die entsprechende Paket-API zum Platzieren beliebiger Objekte in einem Paket) ist als leistungsstarker IPC-Transport konzipiert. Daher ist es nicht angebracht, Paketdaten in einem dauerhaften Speicher abzulegen: Änderungen in der zugrunde liegenden Implementierung der Daten im Paket können ältere Daten unlesbar machen.
Marcos Vasconcelos
1

Sie können es mit PowerPreferenceBibliothek in 3 einfachen Schritten tun !

https://github.com/AliAsadi/PowerPreference

1. Objekt erstellen

Object obj = new Object();

2. Schreiben Sie in die gemeinsame Präferenz

PowerPreference.getDefaultFile().put("object",obj);

3. Das Objekt erhalten

Object obj = PowerPreference.getDefaultFile()
                            .getObject("object", Object.class);
Ali Asadi
quelle
0

Mit diesem Objekt -> TinyDB - Android-Shared-Preferences-Turbo ist es sehr einfach. Sie können die meisten häufig verwendeten Objekte wie Arrays, Ganzzahlen, Zeichenfolgenlisten usw. damit speichern

kc ochibili
quelle
Cool, aber ich denke, das funktioniert nur für Primitie-Typen (String, Double, Int usw.), nicht für benutzerdefinierte Objekte (POJOS)
CommonSenseCode
es funktioniert jetzt für benutzerdefinierte Objekte, überprüfen Sie die ReadMe, es wurde aktualisiert
kc ochibili
0

Sie können Complex Preferences Android - von Felipe Silvestre Library verwenden, um Ihre benutzerdefinierten Objekte zu speichern. Grundsätzlich wird der GSON-Mechanismus zum Speichern von Objekten verwendet.

So speichern Sie ein Objekt in den Einstellungen:

User user = new User();
user.setName("Felipe");
user.setAge(22); 
user.setActive(true); 

ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(
     this, "mypref", MODE_PRIVATE);
complexPreferences.putObject("user", user);
complexPreferences.commit();

Und um es wieder abzurufen:

ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(this, "mypref", MODE_PRIVATE);
User user = complexPreferences.getObject("user", User.class);
Serhii Hrabas
quelle
Paket ist kein universeller Serialisierungsmechanismus. Diese Klasse (und die entsprechende Paket-API zum Platzieren beliebiger Objekte in einem Paket) ist als leistungsstarker IPC-Transport konzipiert. Daher ist es nicht angebracht, Paketdaten in einem dauerhaften Speicher abzulegen: Änderungen in der zugrunde liegenden Implementierung der Daten im Paket können ältere Daten unlesbar machen.
Marcos Vasconcelos
Dies ist veraltet
IgorGanapolsky
0

Sie können GSON mit Gradle Build.gradle verwenden:

implementation 'com.google.code.gson:gson:2.8.0'

Dann in Ihrem Code zum Beispiel Paare von String / Boolean mit Kotlin:

        val nestedData = HashMap<String,Boolean>()
        for (i in 0..29) {
            nestedData.put(i.toString(), true)
        }
        val gson = Gson()
        val jsonFromMap = gson.toJson(nestedData)

Hinzufügen zu SharedPrefs:

        val sharedPrefEditor = context.getSharedPreferences(_prefName, Context.MODE_PRIVATE).edit()
        sharedPrefEditor.putString("sig_types", jsonFromMap)
        sharedPrefEditor.apply()

Um nun Daten abzurufen:

val gson = Gson()
val sharedPref: SharedPreferences = context.getSharedPreferences(_prefName, Context.MODE_PRIVATE)
val json = sharedPref.getString("sig_types", "false")
val type = object : TypeToken<Map<String, Boolean>>() {}.type
val map = gson.fromJson(json, type) as LinkedTreeMap<String,Boolean>
for (key in map.keys) {
     Log.i("myvalues", key.toString() + map.get(key).toString())
}
CAZ
quelle
Paket ist kein universeller Serialisierungsmechanismus. Diese Klasse (und die entsprechende Paket-API zum Platzieren beliebiger Objekte in einem Paket) ist als leistungsstarker IPC-Transport konzipiert. Daher ist es nicht angebracht, Paketdaten in einem dauerhaften Speicher abzulegen: Änderungen in der zugrunde liegenden Implementierung der Daten im Paket können ältere Daten unlesbar machen.
Marcos Vasconcelos
0

Common Shared Preference (CURD) SharedPreference: Zum Speichern von Daten in Form von Wert-Schlüssel-Paaren mit einer einfachen Kotlin-Klasse.

var sp = SharedPreference(this);

Daten speichern:

Zum Speichern von String-, Int- und Booleschen Daten stehen drei Methoden mit demselben Namen und unterschiedlichen Parametern zur Verfügung (Methodenüberladung).

save("key-name1","string value")
save("key-name2",int value)
save("key-name3",boolean)

Daten abrufen: Verwenden Sie die folgenden Methoden, um die in SharedPreferences gespeicherten Daten abzurufen.

sp.getValueString("user_name")
sp.getValueInt("user_id")
sp.getValueBoolean("user_session",true)

Alle Daten löschen: Um die gesamten SharedPreferences zu löschen, verwenden Sie den folgenden Code.

 sp.clearSharedPreference()

Spezifische Daten entfernen:

sp.removeValue("user_name")

Gemeinsame gemeinsame Präferenzklasse

import android.content.Context
import android.content.SharedPreferences

class SharedPreference(private val context: Context) {
    private val PREFS_NAME = "coredata"
    private val sharedPref: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
    //********************************************************************************************** save all
    //To Store String data
    fun save(KEY_NAME: String, text: String) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putString(KEY_NAME, text)
        editor.apply()
    }
    //..............................................................................................
    //To Store Int data
    fun save(KEY_NAME: String, value: Int) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putInt(KEY_NAME, value)
        editor.apply()
    }
    //..............................................................................................
    //To Store Boolean data
    fun save(KEY_NAME: String, status: Boolean) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putBoolean(KEY_NAME, status)
        editor.apply()
    }
    //********************************************************************************************** retrieve selected
    //To Retrieve String
    fun getValueString(KEY_NAME: String): String? {

        return sharedPref.getString(KEY_NAME, "")
    }
    //..............................................................................................
    //To Retrieve Int
    fun getValueInt(KEY_NAME: String): Int {

        return sharedPref.getInt(KEY_NAME, 0)
    }
    //..............................................................................................
    // To Retrieve Boolean
    fun getValueBoolean(KEY_NAME: String, defaultValue: Boolean): Boolean {

        return sharedPref.getBoolean(KEY_NAME, defaultValue)
    }
    //********************************************************************************************** delete all
    // To clear all data
    fun clearSharedPreference() {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.clear()
        editor.apply()
    }
    //********************************************************************************************** delete selected
    // To remove a specific data
    fun removeValue(KEY_NAME: String) {
        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.remove(KEY_NAME)
        editor.apply()
    }
}

Blog: https://androidkeynotes.blogspot.com/2020/02/shared-preference.html

Hari Shankar S.
quelle
-2

Es gibt keine Möglichkeit, Objekte in SharedPreferences zu speichern. Ich habe eine öffentliche Klasse erstellt, alle benötigten Parameter eingegeben und Setter und Getter erstellt. Ich konnte auf meine Objekte zugreifen.

Ismael Ozil
quelle
-3

Müssen Sie das Objekt auch nach dem Herunterfahren der Anwendung oder während der Ausführung abrufen?

Sie können es in einer Datenbank speichern.
Oder erstellen Sie einfach eine benutzerdefinierte Anwendungsklasse.

public class MyApplication extends Application {

    private static Object mMyObject;
    // static getter & setter
    ...
}

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application ... android:name=".MyApplication">
        <activity ... />
        ...
    </application>
    ...
</manifest>

Und dann von jeder Aktivität tun:

((MyApplication) getApplication).getMyObject();

Nicht wirklich der beste Weg, aber es funktioniert.

luc.chante
quelle
-6

Ja. Sie können das Objekt mit Sharedpreference speichern und abrufen

Sukanya
quelle