Jak Android SharedPreferences zapisuje / zapisuje obiekt


216

Musimy zdobyć obiekty użytkownika w wielu miejscach, które zawierają wiele pól. Po zalogowaniu chcę zapisać / zapisać te obiekty użytkownika. Jak możemy wdrożyć tego rodzaju scenariusz?

Nie mogę tego tak przechowywać:

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

jaki typ danych chcesz przechowywać?
— ilango j


Co miałeś na myśli przez ~ „ i obiekt wykonawczy ”? Sprawdź swoją gramatykę przed opublikowaniem na StackOverflow.
— IgorGanapolsky

Możesz użyć tej biblioteki, która ma wiele funkcji ... github.com/moinkhan-in/PreferenceSpider
— Moinkhan

Odpowiedzi:


548

Możesz użyć gson.jar do przechowywania obiektów klasy w SharedPreferences . Możesz pobrać ten słoik z google-gson

Lub dodaj zależność GSON do pliku Gradle:

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

Tworzenie wspólnych preferencji:

SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);

Zapisać:

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

Aby pobrać:

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

9
Dziękuję przyjacielu! Ale jesteś niepoprawny w części Save (wiersz 3), poprawny kod to: String json = gson.toJson (myObject);
— cesarferreira

Potrzebujesz wszystkich 3 słoików? W tym linku znajdują się 3 z nich. . .
— coolcool1994

3
Prawidłowy adres URL do pobierania słoika to: search.maven.org/…
— Shajeel Afzal


1
@rozina tak Gson jest lepszy. Przede wszystkim, aby użyć serializacji, obiekt i każdy znajdujący się w nim obiekt musi implementować interfejs serializacji. Nie jest to potrzebne w przypadku gson. gson działa również świetnie, gdy twoim obiektem jest lista obiektów.
— Neville Nazerane

36

Aby dodać do odpowiedzi @ MuhammadAamirALi, możesz użyć Gsona, aby zapisać i pobrać listę obiektów

Zapisz listę obiektów zdefiniowanych przez użytkownika w SharedPreferences

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

Pobierz listę obiektów zdefiniowanych przez użytkownika z SharedPreferences

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
Co to jest „Typ”? (na liście Get, 2. linia).
— gangadhars

15

Wiem, że ten wątek jest trochę stary. Ale i tak to opublikuję, mając nadzieję, że może komuś pomóc. Możemy przechowywać pola dowolnego obiektu do wspólnych preferencji , serializując obiekt do ciągu. Tutaj użyłem GSONdo przechowywania dowolnego obiektu do wspólnych preferencji.

Zapisz obiekt w preferencjach:

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

Pobierz obiekt z preferencji:

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

Uwaga :

Pamiętaj, aby dodać compile 'com.google.code.gson:gson:2.6.2'do dependenciesswojej oceny.

Przykład :

//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);

Aktualizacja:

Jak wskazał @Sharp_Edge w komentarzach, powyższe rozwiązanie nie działa List.

Niewielka modyfikacja podpisu getSavedObjectFromPreference()- od Class<GenericClass> classTypedo Type classTypespowoduje uogólnienie tego rozwiązania. Zmodyfikowana sygnatura funkcji,

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

Za wywołanie

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

Happy Coding!


1
to było naprawdę pomocne dzięki. Dla każdego, kto chce komentować ... czy powinienem zadzwonić do saveObjectToSharedPreference w onSaveInstanceState? Mam go teraz w onSaveInstanceState, ale biorąc pod uwagę, że moja aplikacja zbiera dane w czasie rzeczywistym co 10 sekund, co jakiś czas dostaję czkawkę, a obiekt, który zapisuję za pomocą saveObjectToSharedPreference, traci pewne odczyty. Wszystkie myśli są mile widziane.
— Frank Zappa,

hej @FrankZappa, wybacz mi nie do końca rozumiem twój problem, ale proszę bardzo, spróbuj użyć commitzamiast apply. To może ci pomóc.
— tpk,

dzięki. Pozwól mi spróbować wyjaśnić. Moja aplikacja na Androida zbiera dane w czasie rzeczywistym co około 10 sekund. Ta kolekcja danych nie używa żadnych obiektów, tylko zmienne globalne i logikę. Następnie dane są następnie podsumowywane i przechowywane w obiekcie Java. Używam powyższej metody do przechowywania i pobierania mojego obiektu Java w / przez SharedPreferences, ponieważ a) o ile wiem, nie mogę przechowywać obiektów w onSavedInstanceState ib) gdy ekran się obraca, mój obiekt zostaje zniszczony i ponownie utworzony. Dlatego używam podejścia SharedPrefs, więc gdy ekran jest obrócony, mój obiekt nie traci swoich wartości. (cd.)
— Frank Zappa,

Umieściłem procedurę saveObjectToSharedPreferences w onSaveInstanceState. Umieściłem twoją procedurę getSavedObjectFromPreference w onRestoreInstanceState. Jednak przetestowałem i nadal otrzymałem jeden zestaw brakujących aktualizacji obiektów ze względu na obrót ekranu. Dlatego powinienem przenieść wywołanie saveObjectToSharedPreferences bliżej mojej logiki? Wreszcie, do jakiej metody się odnosi i stosuje?
— Frank Zappa,

1
@ 2943 Twoje rozwiązanie wygląda świetnie, ale jeśli mam na przykład listę, List<CustomClass>jak mam to zrobić? getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class)nie akceptuje List<CustomClass>.class:(
— Sharp Edge

6

Lepiej jest stworzyć globalną Constantsklasę do zapisywania klucza lub zmiennych w celu pobierania lub zapisywania danych.

Aby zapisać dane, wywołaj tę metodę, aby zapisać dane z dowolnego miejsca.

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

Użyj go, aby uzyskać dane.

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

i metoda taka jak ta załatwi sprawę

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

Co mogę przekazać jako „zmienną” i „defaultValue”, aby odzyskać dane?
— Alex

Nigdy nie twórz klasy Constants. To sprawia, że ​​kod jest bardzo sprzężony i rozproszony w tym samym czasie.
— Miha_x64,

5

Wypróbuj ten najlepszy sposób:

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

}

Napisz wartość:

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

I uzyskaj wartość, używając:

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

2
Co to ma wspólnego z zapisywaniem obiektu w SharedPreferences na Androida?
— IgorGanapolsky

Więcej informacji na temat pracy z Preferencjami współdzielonymi można znaleźć na stackoverflow.com/a/2614771/1815624 notatce, której możesz chcieć użyć return PreferenceManager.getDefaultSharedPreferences(context);zamiastreturn context.getSharedPreferences(PREF_NAME, MODE);
— CrandellWS

3

Po tym nie określiłeś, co robisz z prefsEditorobiektem, ale aby zachować dane preferencji, musisz również użyć:

prefsEditor.commit();

2

Zobacz tutaj, to może ci pomóc:

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
Czy możesz wyjaśnić kod nieco bardziej, ponieważ obecnie reprezentuje on tylko „garść kodu”.
— Werner

1

Innym sposobem zapisywania i przywracania obiektu z udostępnionych preferencji Androida bez użycia formatu Json

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

Możesz zapisać obiekt w preferencjach bez użycia biblioteki, przede wszystkim klasa obiektów musi implementować Serializable:

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

}

Następnie możesz łatwo użyć tych dwóch metod do konwersji obiektu na ciąg i ciągu na obiekt:

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

Zapisać:

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

Czytać

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

Możesz uniknąć kodowania Base64 i ucieczki XML, po prostu zapisując te bajty w osobnym pliku.
— Miha_x64,

1

Krok 1: Skopiuj wklej te dwie funkcje do pliku Java.

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

Krok 2: aby zapisać użyj:

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

aby pobrać użyj:

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

Możesz ustawić różne preferencje wspólne, używając różnych nazw kluczy, takich jak:

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

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

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

1

Jeśli chcesz przechowywać cały obiekt, który otrzymujesz w odpowiedzi, możesz to osiągnąć, robiąc coś takiego,

Najpierw utwórz metodę, która konwertuje JSON na ciąg znaków w klasie util, jak poniżej.

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

Następnie w klasie wspólnych preferencji Zrób coś takiego,

 public void storeLoginResponse(yourResponseClass objName) {

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

a następnie utwórz metodę 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();
    }
}

Następnie po prostu wywołaj pierwszą metodę, gdy otrzymasz odpowiedź, i drugą, gdy musisz uzyskać dane z preferencji udostępniania, takich jak

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

to wszystko.

Mam nadzieję, że ci to pomoże.

Happy Coding();


1

Miałem problem z użyciem zaakceptowanej odpowiedzi w celu uzyskania dostępu do danych Preferencji wspólnych dla różnych działań. W tych krokach nadajesz nazwę getSharedPreferences, aby uzyskać do niej dostęp.

Dodaj następującą zależność w pliku build.gradel (Module: app) w części Skrypty gradle:

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

Zapisać:

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

Aby pobrać inną aktywność:

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'

mam nadzieję, że to ci pomoże :)


1

Oto omówienie korzystania z właściwości delegowanych Kotlin, które wybrałem stąd , ale rozwinąłem i pozwala na prosty mechanizm pobierania / ustawiania właściwości SharedPreference.

Na String, Int, Long, Floati Boolean, że stosuje się standardową metodę pobierania SharePreference (ów) i ustawiającą (S). Jednak dla wszystkich innych klas danych używa GSON do serializacji do a Stringdla setera. Następnie deserializuje do obiektu danych dla gettera.

Podobnie jak w przypadku innych rozwiązań, wymaga to dodania GSON jako zależności w pliku oceny:

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

Oto przykład prostej klasy danych, którą chcielibyśmy móc zapisać i przechowywać w SharedPreferences:

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

Oto jedna klasa, która implementuje delegatów właściwości:

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"
    }
}

Uwaga: nie musisz niczego aktualizować w sealed class. Te przekazane właściwości są przedmiotem / Singleton'y UserPreferenceProperty, NullableUserPreferencePropertyi FirstTimeUser.

Aby skonfigurować nowy obiekt danych do zapisywania / pobierania z SharedPreferences, jest teraz tak proste, jak dodanie czterech linii:

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

Wreszcie możesz odczytywać / zapisywać wartości w SharedPreferences, używając tylko bysłowa kluczowego:

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

Jeśli Twój obiekt jest złożony, sugeruję Serializację / XML / JSON i zapisanie tych treści na karcie SD. Dodatkowe informacje na temat zapisywania w pamięci zewnętrznej można znaleźć tutaj: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal


Czy to nie wymaga dodatkowego pozwolenia (karty SD)?
— rishabh

Tak, ponieważ będziesz pisać na karcie SD.
— trenpixster,

1
Z mojego doświadczenia wynika, że ​​im mniejsze uprawnienia wymagane od użytkownika, tym lepiej. Karta SD powinna być drugorzędnym wyborem, jeśli korzystanie z Gson, jak wspomniano powyżej, nie jest wykonalną opcją.
— rishabh

Tak, zgadzam się z tym; Tylko jeśli wynik JSON jest wystarczająco duży, karta SD powinna być opcją. Powiedziałbym, że to kompromis.
— trenpixster,

0

są dwa pliki rozwiązujące cały problem dotyczący wspólnych preferencji

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

teraz możesz zapisać, usunąć lub uzyskać,

-zapisać

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

-usunąć

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

-dostać

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

0

Przechowuj dane w SharedPreference

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

0

Moja klasa utils do listy zapisywania w 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);
    }
}

Za pomocą

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

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

.
Pełny kod moich narzędzi // sprawdź, korzystając z przykładu w kodzie działania


0

Użyłem Jacksona do przechowywania moich obiektów ( Jackson ).

Dodano bibliotekę Jacksona do oceny:

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'

Moja klasa testowa:

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

Obiekt Java do JSON:

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

Zapisz go we wspólnych preferencjach:

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

Przywróć z wspólnych preferencji:

ObjectMapper objectMapper = new ObjectMapper();
Car car = objectMapper.readValue(preferences.car().get(), Car.class);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.