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);
Piraba
źródło
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);
Muhammad Aamir Ali
źródło
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
2
Występuje
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);
toobsco42
źródło
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!

tpk
źródło
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;
}
Adil Soomro
źródło
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, "");
Girish Patel
źródło
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();
RivieraKid
źródło
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

Altas
źródło
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();
        }
William Desportes
źródło
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);
farhad.kargaran
źródło
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);
Viraj Singh
źródło
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();

Naresh
źródło
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);
Ben
źródło
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","[email protected]","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 :)

użytkownik7168064
źródło
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
Jason Grife
źródło
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

trenpixster
źródło
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);
Gautam Surani
źródło
0

Przechowuj dane w SharedPreference

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

źródło
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

Phan Van Linh
źródło
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);
Manuel Schmitzberger
źródło