Wie Android SharedPreferences Objekte speichern / speichern


214

Wir müssen Benutzerobjekte an vielen Stellen abrufen, die viele Felder enthalten. Nach dem Login möchte ich diese Benutzerobjekte speichern / speichern. Wie können wir ein solches Szenario implementieren?

Ich kann es nicht so speichern:

SharedPreferences.Editor prefsEditor = myPrefs.edit();
prefsEditor.putString("BusinessUnit", strBusinessUnit);

Welche Art von Daten möchten Sie speichern?
Ilango J


Was meinten Sie mit ~ " und Executive Object "? Bitte überprüfen Sie Ihre Grammatik, bevor Sie auf StackOverflow posten.
IgorGanapolsky

Sie können diese Bibliothek verwenden, die viele Funktionen hat ... github.com/moinkhan-in/PreferenceSpider
Moinkhan

Antworten:


547

Sie können gson.jar zu speichern Klassenobjekte in verwenden SharedPreferences . Sie können dieses Glas von herunterladen Google-Gson herunterladen

Oder fügen Sie die GSON-Abhängigkeit in Ihre Gradle-Datei ein:

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

Gemeinsame Einstellungen erstellen:

SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);

Speichern:

MyObject myObject = new MyObject;
//set variables of 'myObject', etc.

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

So rufen Sie ab:

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

9
Danke Freund! Aber Sie sind im Save-Teil (Zeile 3) falsch. Der richtige Code lautet: String json = gson.toJson (myObject);
Cesarferreira

Benötigen Sie alle 3 Gläser? Es gibt 3 von ihnen in diesem Link. . .
coolcool1994

3
Die richtige URL zum Herunterladen des JARs
Shajeel Afzal

2
Dies hat ein Problem mit Zirkelverweis
Phuwin

1
@rozina ja Gson ist besser. Um serialize zu verwenden, müssen zunächst das Objekt und jedes darin enthaltene Objekt die serialize-Schnittstelle implementieren. Dies wird für gson nicht benötigt. gson funktioniert auch hervorragend, wenn Ihr Objekt eine Liste von Objekten ist.
Neville Nazerane

36

Um die Antwort von @ MuhammadAamirALi zu ergänzen, können Sie mit Gson eine Liste von Objekten speichern und abrufen

Liste der benutzerdefinierten Objekte in SharedPreferences speichern

public static final String KEY_CONNECTIONS = "KEY_CONNECTIONS";
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();

User entity = new User();
// ... set entity fields

List<Connection> connections = entity.getConnections();
// convert java object to JSON format,
// and returned as JSON formatted string
String connectionsJSONString = new Gson().toJson(connections);
editor.putString(KEY_CONNECTIONS, connectionsJSONString);
editor.commit();

Liste der benutzerdefinierten Objekte aus SharedPreferences abrufen

String connectionsJSONString = getPreferences(MODE_PRIVATE).getString(KEY_CONNECTIONS, null);
Type type = new TypeToken < List < Connection >> () {}.getType();
List < Connection > connections = new Gson().fromJson(connectionsJSONString, type);

3
Was ist "Typ" dort? (in Get-Liste, 2. Zeile).
Gangadhars

15

Ich weiß, dass dieser Thread etwas alt ist. Aber ich werde das trotzdem posten, in der Hoffnung, dass es jemandem helfen könnte. Wir können Felder eines beliebigen Objekts nach gemeinsamen Vorgaben speichern, indem wir das Objekt in String serialisieren . Hier habe ich GSONzum Speichern eines Objekts nach gemeinsamen Vorlieben verwendet.

Objekt in den Einstellungen speichern:

public static void saveObjectToSharedPreference(Context context, String preferenceFileName, String serializedObjectKey, Object object) {
    SharedPreferences sharedPreferences = context.getSharedPreferences(preferenceFileName, 0);
    SharedPreferences.Editor sharedPreferencesEditor = sharedPreferences.edit();
    final Gson gson = new Gson();
    String serializedObject = gson.toJson(object);
    sharedPreferencesEditor.putString(serializedObjectKey, serializedObject);
    sharedPreferencesEditor.apply();
}

Objekt aus den Einstellungen abrufen:

public static <GenericClass> GenericClass getSavedObjectFromPreference(Context context, String preferenceFileName, String preferenceKey, Class<GenericClass> classType) {
    SharedPreferences sharedPreferences = context.getSharedPreferences(preferenceFileName, 0);
    if (sharedPreferences.contains(preferenceKey)) {
        final Gson gson = new Gson();
        return gson.fromJson(sharedPreferences.getString(preferenceKey, ""), classType);
    }
    return null;
}

Hinweis :

Denken Sie daran compile 'com.google.code.gson:gson:2.6.2', dependenciesin Ihrem Gradle hinzuzufügen.

Beispiel :

//assume SampleClass exists
SampleClass mObject = new SampleObject();

//to store an object
saveObjectToSharedPreference(context, "mPreference", "mObjectKey", mObject);

//to retrive object stored in preference
mObject = getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class);

Aktualisieren:

Wie @Sharp_Edge in den Kommentaren hervorhob, funktioniert die obige Lösung nicht List .

Durch eine geringfügige Änderung der Signatur von getSavedObjectFromPreference()- von Class<GenericClass> classTypebis Type classTypewird diese Lösung verallgemeinert. Geänderte Funktionssignatur,

public static <GenericClass> GenericClass getSavedObjectFromPreference(Context context, String preferenceFileName, String preferenceKey, Type classType)

Zum Aufrufen,

getSavedObjectFromPreference(context, "mPreference", "mObjectKey", (Type) SampleClass.class)

Viel Spaß beim Codieren!


1
Das war wirklich hilfreich, danke. Für alle hier, die einen Kommentar abgeben möchten ... sollte ich den Aufruf von saveObjectToSharedPreference in onSaveInstanceState setzen? Ich habe es jetzt in onSaveInstanceState, aber da meine App alle 10 Sekunden Echtzeitdaten sammelt, bekomme ich gelegentlich einen Schluckauf und das Objekt, das ich mit saveObjectToSharedPreference speichere, verliert einige Messwerte. Alle Gedanken sind willkommen.
Frank Zappa

hey @FrankZappa, vergib mir, dass ich dein Problem nicht vollständig verstehe, aber los geht's, versuche es commitstatt apply. Es könnte dir helfen.
tpk

Vielen Dank. Lassen Sie mich versuchen zu erklären. Meine Android-App sammelt ungefähr alle 10 Sekunden Daten in Echtzeit. Diese Datenerfassung verwendet keine Objekte, nur globale Variablen und Logik. Als nächstes werden die Daten zusammengefasst und in einem Java-Objekt gespeichert. Ich verwende die oben beschriebene Methode, um mein Java-Objekt in / über SharedPreferences zu speichern und abzurufen, da a) meines Wissens keine Objekte in onSavedInstanceState gespeichert werden können und b) wenn sich der Bildschirm dreht, wird mein Objekt zerstört und neu erstellt. Daher verwende ich Ihren SharedPrefs-Ansatz, damit mein Objekt beim Drehen des Bildschirms nicht seine Werte verliert. (Fortsetzung)
Frank Zappa

Ich habe Ihre Routine saveObjectToSharedPreferences in onSaveInstanceState platziert. Ich habe Ihre Routine getSavedObjectFromPreference in onRestoreInstanceState platziert. Ich habe jedoch einen Satz fehlender Objektaktualisierungen aufgrund der Bildschirmdrehung getestet und immer noch erhalten. Sollte ich den Aufruf von saveObjectToSharedPreferences daher näher an meine eigentliche Logik verschieben? Zu welcher Methode gehört das Festschreiben und Anwenden?
Frank Zappa

1
@ 2943 Ihre Lösung sieht gut aus, aber wenn ich zum Beispiel eine Liste habe, List<CustomClass>wie soll ich das machen? getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class)akzeptiert nicht List<CustomClass>.class:(
Sharp Edge

6

Besser ist es, eine globale zu machen Constants Klasse zum Speichern von Schlüsseln oder Variablen zum Abrufen oder Speichern von Daten zu erstellen.

Um Daten zu speichern, rufen Sie diese Methode auf, um Daten von jedem Ort zu speichern.

public static void saveData(Context con, String variable, String data)
{
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(con);
    prefs.edit().putString(variable, data).commit();
}

Verwenden Sie es, um Daten abzurufen.

public static String getData(Context con, String variable, String defaultValue)
{
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(con);
    String data = prefs.getString(variable, defaultValue);
    return data;
}

und eine Methode wie diese wird den Trick tun

public static User getUserInfo(Context con)
{
    String id =  getData(con, Constants.USER_ID, null);
    String name =  getData(con, Constants.USER_NAME, null);
    if(id != null && name != null)
    {
            User user = new User(); //Hope you will have a user Object.
            user.setId(id);
            user.setName(name);
            //Here set other credentials.
            return user;
    }
    else
    return null;
}

Was übergebe ich als 'Variable' und 'Standardwert', um die Daten zurückzugewinnen?
Alex

Erstellen Sie niemals eine Konstantenklasse. Dadurch wird Ihr Code stark gekoppelt und gleichzeitig verstreut.
Miha_x64

5

Versuchen Sie dies am besten:

PreferenceConnector.java

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class PreferenceConnector {
    public static final String PREF_NAME = "ENUMERATOR_PREFERENCES";
    public static final String PREF_NAME_REMEMBER = "ENUMERATOR_REMEMBER";
    public static final int MODE = Context.MODE_PRIVATE;


    public static final String name = "name";


    public static void writeBoolean(Context context, String key, boolean value) {
        getEditor(context).putBoolean(key, value).commit();
    }

    public static boolean readBoolean(Context context, String key,
            boolean defValue) {
        return getPreferences(context).getBoolean(key, defValue);
    }

    public static void writeInteger(Context context, String key, int value) {
        getEditor(context).putInt(key, value).commit();

    }

    public static int readInteger(Context context, String key, int defValue) {
        return getPreferences(context).getInt(key, defValue);
    }

    public static void writeString(Context context, String key, String value) {
        getEditor(context).putString(key, value).commit();

    }

    public static String readString(Context context, String key, String defValue) {
        return getPreferences(context).getString(key, defValue);
    }

    public static void writeLong(Context context, String key, long value) {
        getEditor(context).putLong(key, value).commit();
    }

    public static long readLong(Context context, String key, long defValue) {
        return getPreferences(context).getLong(key, defValue);
    }

    public static SharedPreferences getPreferences(Context context) {
        return context.getSharedPreferences(PREF_NAME, MODE);
    }

    public static Editor getEditor(Context context) {
        return getPreferences(context).edit();
    }

}

Schreiben Sie den Wert:

PreferenceConnector.writeString(this, PreferenceConnector.name,"Girish");

Und erhalten Sie Wert mit:

String name= PreferenceConnector.readString(this, PreferenceConnector.name, "");

2
Was hat dies mit dem Speichern eines Objekts in SharedPreferences unter Android zu tun?
IgorGanapolsky

Weitere Informationen zum Arbeiten mit Sharedpreferences finden Sie unter stackoverflow.com/a/2614771/1815624 Hinweis, den Sie möglicherweise return PreferenceManager.getDefaultSharedPreferences(context);anstelle vonreturn context.getSharedPreferences(PREF_NAME, MODE);
CrandellWS

3

Sie haben danach nicht angegeben, was Sie mit dem prefsEditorObjekt tun , aber um die Präferenzdaten beizubehalten, müssen Sie außerdem Folgendes verwenden:

prefsEditor.commit();

2

Sehen Sie hier, dies kann Ihnen helfen:

public static boolean setObject(Context context, Object o) {
        Field[] fields = o.getClass().getFields();
        SharedPreferences sp = context.getSharedPreferences(o.getClass()
                .getName(), Context.MODE_PRIVATE);
        Editor editor = sp.edit();
        for (int i = 0; i < fields.length; i++) {
            Class<?> type = fields[i].getType();
            if (isSingle(type)) {
                try {
                    final String name = fields[i].getName();
                    if (type == Character.TYPE || type.equals(String.class)) {
                        Object value = fields[i].get(o);
                        if (null != value)
                            editor.putString(name, value.toString());
                    } else if (type.equals(int.class)
                            || type.equals(Short.class))
                        editor.putInt(name, fields[i].getInt(o));
                    else if (type.equals(double.class))
                        editor.putFloat(name, (float) fields[i].getDouble(o));
                    else if (type.equals(float.class))
                        editor.putFloat(name, fields[i].getFloat(o));
                    else if (type.equals(long.class))
                        editor.putLong(name, fields[i].getLong(o));
                    else if (type.equals(Boolean.class))
                        editor.putBoolean(name, fields[i].getBoolean(o));

                } catch (IllegalAccessException e) {
                    LogUtils.e(TAG, e);
                } catch (IllegalArgumentException e) {
                    LogUtils.e(TAG, e);
                }
            } else {
                // FIXME 是对象则不写入
            }
        }

        return editor.commit();
    }

https://github.com/AltasT/PreferenceVObjectFile/blob/master/PreferenceVObjectFile/src/com/altas/lib/PreferenceUtils.java


2
Könnten Sie den Code etwas näher erläutern, da dies derzeit nur "eine Menge Code" darstellt?
Werner

1

Eine andere Möglichkeit, ein Objekt aus freigegebenen Android-Einstellungen zu speichern und wiederherzustellen, ohne das Json-Format zu verwenden

private static ExampleObject getObject(Context c,String db_name){
            SharedPreferences sharedPreferences = c.getSharedPreferences(db_name, Context.MODE_PRIVATE);
            ExampleObject o = new ExampleObject();
            Field[] fields = o.getClass().getFields();
            try {
                for (Field field : fields) {
                    Class<?> type = field.getType();
                    try {
                        final String name = field.getName();
                        if (type == Character.TYPE || type.equals(String.class)) {
                            field.set(o,sharedPreferences.getString(name, ""));
                        } else if (type.equals(int.class) || type.equals(Short.class))
                            field.setInt(o,sharedPreferences.getInt(name, 0));
                        else if (type.equals(double.class))
                            field.setDouble(o,sharedPreferences.getFloat(name, 0));
                        else if (type.equals(float.class))
                            field.setFloat(o,sharedPreferences.getFloat(name, 0));
                        else if (type.equals(long.class))
                            field.setLong(o,sharedPreferences.getLong(name, 0));
                        else if (type.equals(Boolean.class))
                            field.setBoolean(o,sharedPreferences.getBoolean(name, false));
                        else if (type.equals(UUID.class))
                            field.set(
                                    o,
                                    UUID.fromString(
                                            sharedPreferences.getString(
                                                    name,
                                                    UUID.nameUUIDFromBytes("".getBytes()).toString()
                                            )
                                    )
                            );

                    } catch (IllegalAccessException e) {
                        Log.e(StaticConfig.app_name, "IllegalAccessException", e);
                    } catch (IllegalArgumentException e) {
                        Log.e(StaticConfig.app_name, "IllegalArgumentException", e);
                    }
                }
            } catch (Exception e) {
                System.out.println("Exception: " + e);
            }
            return o;
        }
        private static void setObject(Context context, Object o, String db_name) {
            Field[] fields = o.getClass().getFields();
            SharedPreferences sp = context.getSharedPreferences(db_name, Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            for (Field field : fields) {
                Class<?> type = field.getType();
                try {
                    final String name = field.getName();
                    if (type == Character.TYPE || type.equals(String.class)) {
                        Object value = field.get(o);
                        if (value != null)
                            editor.putString(name, value.toString());
                    } else if (type.equals(int.class) || type.equals(Short.class))
                        editor.putInt(name, field.getInt(o));
                    else if (type.equals(double.class))
                        editor.putFloat(name, (float) field.getDouble(o));
                    else if (type.equals(float.class))
                        editor.putFloat(name, field.getFloat(o));
                    else if (type.equals(long.class))
                        editor.putLong(name, field.getLong(o));
                    else if (type.equals(Boolean.class))
                        editor.putBoolean(name, field.getBoolean(o));
                    else if (type.equals(UUID.class))
                        editor.putString(name, field.get(o).toString());

                } catch (IllegalAccessException e) {
                    Log.e(StaticConfig.app_name, "IllegalAccessException", e);
                } catch (IllegalArgumentException e) {
                    Log.e(StaticConfig.app_name, "IllegalArgumentException", e);
                }
            }

            editor.apply();
        }

1

Sie können Objekte in Einstellungen speichern, ohne eine Bibliothek zu verwenden. Zunächst muss Ihre Objektklasse Serializable implementieren:

public class callModel implements Serializable {

private long pointTime;
private boolean callisConnected;

public callModel(boolean callisConnected,  long pointTime) {
    this.callisConnected = callisConnected;
    this.pointTime = pointTime;
}
public boolean isCallisConnected() {
    return callisConnected;
}
public long getPointTime() {
    return pointTime;
}

}}

Dann können Sie diese beiden Methoden leicht verwenden, um Objekt in Zeichenfolge und Zeichenfolge in Objekt zu konvertieren:

 public static <T extends Serializable> T stringToObjectS(String string) {
    byte[] bytes = Base64.decode(string, 0);
    T object = null;
    try {
        ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
        object = (T) objectInputStream.readObject();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return object;
}

 public static String objectToString(Parcelable object) {
    String encoded = null;
    try {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(object);
        objectOutputStream.close();
        encoded = new String(Base64.encodeToString(byteArrayOutputStream.toByteArray(), 0));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return encoded;
}

Speichern:

SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);
Editor prefsEditor = mPrefs.edit();
prefsEditor.putString("MyObject", objectToString(callModelObject));
prefsEditor.commit();

Lesen

String value= mPrefs.getString("MyObject", "");
MyObject obj = stringToObjectS(value);

Sie können die Base64-Codierung und das Entweichen von XML vermeiden, indem Sie diese Bytes einfach in eine separate Datei schreiben.
Miha_x64

1

Schritt 1: Kopieren Sie diese beiden Funktionen und fügen Sie sie in Ihre Java-Datei ein.

 public void setDefaults(String key, String value, Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString(key, value);
        editor.commit();
    }


    public static String getDefaults(String key, Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(key, null);
    }

Schritt 2: Speichern der Verwendung:

 setDefaults("key","value",this);

Verwendung abrufen:

String retrieve= getDefaults("key",this);

Sie können verschiedene gemeinsame Einstellungen festlegen, indem Sie verschiedene Schlüsselnamen verwenden, z.

setDefaults("key1","xyz",this);

setDefaults("key2","abc",this);

setDefaults("key3","pqr",this);

1

Wenn Sie das gesamte Objekt speichern möchten, das Sie als Antwort erhalten, können Sie dies erreichen, indem Sie Folgendes tun:

Erstellen Sie zunächst eine Methode, die Ihren JSON in eine Zeichenfolge in Ihrer util-Klasse konvertiert (siehe unten).

 public static <T> T fromJson(String jsonString, Class<T> theClass) {
    return new Gson().fromJson(jsonString, theClass);
}

Dann machen Sie in der Klasse für gemeinsame Einstellungen so etwas wie:

 public void storeLoginResponse(yourResponseClass objName) {

    String loginJSON = UtilClass.toJson(customer);
    if (!TextUtils.isEmpty(customerJSON)) {
        editor.putString(AppConst.PREF_CUSTOMER, customerJSON);
        editor.commit();
    }
}

und erstellen Sie dann eine Methode für getPreferences

public Customer getCustomerDetails() {
    String customerDetail = pref.getString(AppConst.PREF_CUSTOMER, null);
    if (!TextUtils.isEmpty(customerDetail)) {
        return GSONConverter.fromJson(customerDetail, Customer.class);
    } else {
        return new Customer();
    }
}

Rufen Sie dann einfach die erste Methode auf, wenn Sie eine Antwort erhalten, und die zweite, wenn Sie Daten aus Freigabeeinstellungen wie erhalten möchten

String token = SharedPrefHelper.get().getCustomerDetails().getAccessToken();

das ist alles.

Hoffe es wird dir helfen.

Happy Coding();


1

Ich hatte Probleme, die akzeptierte Antwort zu verwenden, um über Aktivitäten hinweg auf gemeinsame Voreinstellungsdaten zuzugreifen. In diesen Schritten geben Sie getSharedPreferences einen Namen, um darauf zuzugreifen.

Fügen Sie der Datei build.gradel (Modul: App) unter Gradle Scripts die folgende Abhängigkeit hinzu:

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

Speichern:

MyObject myObject = new MyObject;
//set variables of 'myObject', etc.

SharedPreferences mPrefs = getSharedPreferences("Name", Context.MODE_PRIVATE);

Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(myObject);
prefsEditor.putString("Key", json);
prefsEditor.commit();

So rufen Sie in einer anderen Aktivität ab:

SharedPreferences mPrefs = getSharedPreferences("Name", Context.MODE_PRIVATE);

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

1
// SharedPrefHelper is a class contains the get and save sharedPrefernce data
public class SharedPrefHelper {

    // save data in sharedPrefences
    public static void setSharedOBJECT(Context context, String key, 
                                           Object value) {

        SharedPreferences sharedPreferences =  context.getSharedPreferences(
                context.getPackageName(), Context.MODE_PRIVATE);

        SharedPreferences.Editor prefsEditor = sharedPreferences.edit();
        Gson gson = new Gson();
        String json = gson.toJson(value);
        prefsEditor.putString(key, json);
        prefsEditor.apply();
    }

    // get data from sharedPrefences 
    public static Object getSharedOBJECT(Context context, String key) {

         SharedPreferences sharedPreferences = context.getSharedPreferences(
                           context.getPackageName(), Context.MODE_PRIVATE);

        Gson gson = new Gson();
        String json = sharedPreferences.getString(key, "");
        Object obj = gson.fromJson(json, Object.class);
        User objData = new Gson().fromJson(obj.toString(), User.class);
        return objData;
    }
}
// save data in your activity

User user = new User("Hussein","h@h.com","3107310890983");        
SharedPrefHelper.setSharedOBJECT(this,"your_key",user);        
User data = (User) SharedPrefHelper.getSharedOBJECT(this,"your_key");

Toast.makeText(this,data.getName()+"\n"+data.getEmail()+"\n"+data.getPhone(),Toast.LENGTH_LONG).show();
// User is the class you want to save its objects

public class User {

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    private String name,email,phone;
    public User(String name,String email,String phone){
          this.name=name;
          this.email=email;
          this.phone=phone;
    }
}
// put this in gradle

compile 'com.google.code.gson:gson:2.7'

hoffe das hilft dir :)


1

Hier ist eine Einführung in die Verwendung von Kotlin-delegierten Eigenschaften , die ich hier aufgenommen habe , aber erweitert habe und die einen einfachen Mechanismus zum Abrufen / Festlegen von SharedPreference-Eigenschaften ermöglicht.

Für String, Int, Long, Floatoder Boolean, verwendet es den Standard SharePreference Getter (n) und Setter (s). Für alle anderen Datenklassen wird jedoch GSON verwendet, um zu a zu serialisierenString , um für den Setter . Deserialisiert dann auf das Datenobjekt für den Getter.

Ähnlich wie bei anderen Lösungen muss dazu GSON als Abhängigkeit in Ihre Gradle-Datei eingefügt werden:

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

Hier ist ein Beispiel für eine einfache Datenklasse, die wir in SharedPreferences speichern und speichern möchten:

data class User(val first: String, val last: String)

Hier ist die eine Klasse, die die Eigenschaftsdelegierten implementiert:

object UserPreferenceProperty : PreferenceProperty<User>(
    key = "USER_OBJECT",
    defaultValue = User(first = "Jane", last = "Doe"),
    clazz = User::class.java)

object NullableUserPreferenceProperty : NullablePreferenceProperty<User?, User>(
    key = "NULLABLE_USER_OBJECT",
    defaultValue = null,
    clazz = User::class.java)

object FirstTimeUser : PreferenceProperty<Boolean>(
        key = "FIRST_TIME_USER",
        defaultValue = false,
        clazz = Boolean::class.java
)

sealed class PreferenceProperty<T : Any>(key: String,
                                         defaultValue: T,
                                         clazz: Class<T>) : NullablePreferenceProperty<T, T>(key, defaultValue, clazz)

@Suppress("UNCHECKED_CAST")
sealed class NullablePreferenceProperty<T : Any?, U : Any>(private val key: String,
                                                           private val defaultValue: T,
                                                           private val clazz: Class<U>) : ReadWriteProperty<Any, T> {

    override fun getValue(thisRef: Any, property: KProperty<*>): T = HandstandApplication.appContext().getPreferences()
            .run {
                when {
                    clazz.isAssignableFrom(String::class.java) -> getString(key, defaultValue as String?) as T
                    clazz.isAssignableFrom(Int::class.java) -> getInt(key, defaultValue as Int) as T
                    clazz.isAssignableFrom(Long::class.java) -> getLong(key, defaultValue as Long) as T
                    clazz.isAssignableFrom(Float::class.java) -> getFloat(key, defaultValue as Float) as T
                    clazz.isAssignableFrom(Boolean::class.java) -> getBoolean(key, defaultValue as Boolean) as T
                    else -> getObject(key, defaultValue, clazz)
                }
            }

    override fun setValue(thisRef: Any, property: KProperty<*>, value: T) = HandstandApplication.appContext().getPreferences()
            .edit()
            .apply {
                when {
                    clazz.isAssignableFrom(String::class.java) -> putString(key, value as String?) as T
                    clazz.isAssignableFrom(Int::class.java) -> putInt(key, value as Int) as T
                    clazz.isAssignableFrom(Long::class.java) -> putLong(key, value as Long) as T
                    clazz.isAssignableFrom(Float::class.java) -> putFloat(key, value as Float) as T
                    clazz.isAssignableFrom(Boolean::class.java) -> putBoolean(key, value as Boolean) as T
                    else -> putObject(key, value)
                }
            }
            .apply()

    private fun Context.getPreferences(): SharedPreferences = getSharedPreferences(APP_PREF_NAME, Context.MODE_PRIVATE)

    private fun <T, U> SharedPreferences.getObject(key: String, defValue: T, clazz: Class<U>): T =
            Gson().fromJson(getString(key, null), clazz) as T ?: defValue

    private fun <T> SharedPreferences.Editor.putObject(key: String, value: T) = putString(key, Gson().toJson(value))

    companion object {
        private const val APP_PREF_NAME = "APP_PREF"
    }
}

Hinweis: Sie sollten nichts in der aktualisieren müssen sealed class. Die delegierten Eigenschaften sind das Objekt / Singletons UserPreferenceProperty, NullableUserPreferencePropertyundFirstTimeUser .

Das Einrichten eines neuen Datenobjekts zum Speichern / Abrufen von SharedPreferences ist jetzt so einfach wie das Hinzufügen von vier Zeilen:

object NewPreferenceProperty : PreferenceProperty<String>(
        key = "NEW_PROPERTY",
        defaultValue = "",
        clazz = String::class.java)

Schließlich können Sie Werte in SharedPreferences lesen / schreiben, indem Sie einfach das bySchlüsselwort verwenden:

private var user: User by UserPreferenceProperty
private var nullableUser: User? by NullableUserPreferenceProperty
private var isFirstTimeUser: Boolean by 

Log.d("TAG", user) // outputs the `defaultValue` for User the first time
user = User(first = "John", last = "Doe") // saves this User to the Shared Preferences
Log.d("TAG", user) // outputs the newly retrieved User (John Doe) from Shared Preferences

0

Wenn Ihr Objekt komplex ist, würde ich vorschlagen, es zu serialisieren / XML / JSON und diese Inhalte auf der SD-Karte zu speichern. Weitere Informationen zum Speichern im externen Speicher finden Sie hier: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal


Benötigt das keine zusätzliche Erlaubnis (SD-Karte)?
Rishabh

Ja, da Sie auf die SD-Karte schreiben würden.
Trenpixster

1
Nach meiner Erfahrung ist es umso besser, je weniger Berechtigungen für den Benutzer erforderlich sind. Die SD-Karte sollte eine sekundäre Wahl sein, wenn die Verwendung von Gson wie oben angegeben keine praktikable Option ist.
Rishabh

Ja, dem stimme ich auch zu; Nur wenn das JSON-Ergebnis groß genug ist, sollte die SD-Karte eine Option sein. Es ist ein Kompromiss, würde ich sagen.
Trenpixster

0

Es gibt zwei Dateien, die Ihr Problem mit gemeinsam genutzten Einstellungen gelöst haben

1) AppPersistence.java

    public class AppPersistence {
    public enum keys {
        USER_NAME, USER_ID, USER_NUMBER, USER_EMAIL, USER_ADDRESS, CITY, USER_IMAGE,
        DOB, MRG_Anniversary, COMPANY, USER_TYPE, support_phone
    }

    private static AppPersistence mAppPersistance;
    private SharedPreferences sharedPreferences;

    public static AppPersistence start(Context context) {
        if (mAppPersistance == null) {
            mAppPersistance = new AppPersistence(context);
        }
        return mAppPersistance;
    }

    private AppPersistence(Context context) {
        sharedPreferences = context.getSharedPreferences(context.getString(R.string.prefrence_file_name),
                Context.MODE_PRIVATE);
    }

    public Object get(Enum key) {
        Map<String, ?> all = sharedPreferences.getAll();
        return all.get(key.toString());
    }

    void save(Enum key, Object val) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        if (val instanceof Integer) {
            editor.putInt(key.toString(), (Integer) val);
        } else if (val instanceof String) {
            editor.putString(key.toString(), String.valueOf(val));
        } else if (val instanceof Float) {
            editor.putFloat(key.toString(), (Float) val);
        } else if (val instanceof Long) {
            editor.putLong(key.toString(), (Long) val);
        } else if (val instanceof Boolean) {
            editor.putBoolean(key.toString(), (Boolean) val);
        }
        editor.apply();
    }

    void remove(Enum key) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.remove(key.toString());
        editor.apply();
    }

    public void removeAll() {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.clear();
        editor.apply();
    }
}

2) AppPreference.java

public static void setPreference(Context context, Enum Name, String Value) {
        AppPersistence.start(context).save(Name, Value);
    }

    public static String getPreference(Context context, Enum Name) {
        return (String) AppPersistence.start(context).get(Name);
    }

    public static void removePreference(Context context, Enum Name) {
        AppPersistence.start(context).remove(Name);
    }
}

Jetzt können Sie speichern, entfernen oder erhalten,

-sparen

AppPreference.setPreference(context, AppPersistence.keys.USER_ID, userID);

-entfernen

AppPreference.removePreference(context, AppPersistence.keys.USER_ID);

-bekommen

 AppPreference.getPreference(context, AppPersistence.keys.USER_ID);

0

Speichern Sie Daten in SharedPreference

SharedPreferences mprefs = getSharedPreferences(AppConstant.PREFS_NAME, MODE_PRIVATE)
mprefs.edit().putString(AppConstant.USER_ID, resUserID).apply();

0

Meine Utensilienklasse zum Speichern der Liste an SharedPreferences

public class SharedPrefApi {
    private SharedPreferences sharedPreferences;
    private Gson gson;

    public SharedPrefApi(Context context, Gson gson) {
        this.sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        this.gson = gson;
    } 

    ...

    public <T> void putObject(String key, T value) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, gson.toJson(value));
        editor.apply();
    }

    public <T> T getObject(String key, Class<T> clazz) {
        return gson.fromJson(getString(key, null), clazz);
    }
}

Verwenden von

// for save
sharedPrefApi.putList(SharedPrefApi.Key.USER_LIST, userList);

// for retrieve
List<User> userList = sharedPrefApi.getList(SharedPrefApi.Key.USER_LIST, User.class);

.
Vollständiger Code meiner Utils // Überprüfen Sie anhand eines Beispiels im Aktivitätscode


0

Ich habe Jackson verwendet, um meine Objekte zu speichern ( Jackson ).

Jackson-Bibliothek zum Gradle hinzugefügt:

api 'com.fasterxml.jackson.core:jackson-core:2.9.4'
api 'com.fasterxml.jackson.core:jackson-annotations:2.9.4'
api 'com.fasterxml.jackson.core:jackson-databind:2.9.4'

Meine Testklasse:

public class Car {
    private String color;
    private String type;
    // standard getters setters
}

Java-Objekt zu JSON:

ObjectMapper objectMapper = new ObjectMapper();
String carAsString = objectMapper.writeValueAsString(car);

Speichern Sie es in gemeinsamen Einstellungen:

preferences.edit().car().put(carAsString).apply();

Stellen Sie es aus den freigegebenen Einstellungen wieder her:

ObjectMapper objectMapper = new ObjectMapper();
Car car = objectMapper.readValue(preferences.car().get(), Car.class);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.