Как Android SharedPreferences сохраняет / хранит объект

217

Нам нужно получить пользовательские объекты во многих местах, которые содержат много полей. После входа в систему я хочу сохранить / сохранить эти пользовательские объекты. Как мы можем реализовать такой сценарий?

Я не могу хранить это так:

SharedPreferences.Editor prefsEditor = myPrefs.edit();
prefsEditor.putString("BusinessUnit", strBusinessUnit);
Piraba
источник
какой тип данных вы хотите хранить?
ilango j
Что вы имели в виду под ~ " и исполнительный объект "? Пожалуйста, проверьте свою грамматику перед публикацией в StackOverflow.
Игорь Ганапольский
Вы можете использовать эту библиотеку, которая имеет много функций ... github.com/moinkhan-in/PreferenceSpider
Moinkhan

Ответы:

549

Вы можете использовать gson.jar для хранения объектов класса в SharedPreferences . Вы можете скачать эту банку с Google-GSON

Или добавьте зависимость GSON в ваш файл Gradle:

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

Создание общего предпочтения:

SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);

Сохранить:

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

Чтобы получить:

Gson gson = new Gson();
String json = mPrefs.getString("MyObject", "");
MyObject obj = gson.fromJson(json, MyObject.class);
Мухаммед Амир Али
источник
9
Спасибо друг! Но вы ошиблись в части Сохранить (строка 3), правильный код: String json = gson.toJson (myObject);
Чезарферрейра
Вам нужны все 3 банки? Есть 3 из них по этой ссылке. , ,
coolcool1994
3
Правильный URL-адрес для загрузки банки: search.maven.org/…
Shajeel Afzal
2
Это имеет проблему с циклической ссылкой, которая приводит к StackOverFlowException xD Подробнее здесь stackoverflow.com/questions/10209959/…
phuwin
1
@rozina да Гсон лучше. Прежде всего, чтобы использовать сериализацию, объект и каждый объект внутри него должны реализовать интерфейс сериализации. Это не нужно для GSON. gson также отлично работает, когда ваш объект представляет собой список объектов.
Невилл Назеране
36

Чтобы добавить ответ @ MuhammadAamirALi, вы можете использовать Gson для сохранения и получения списка объектов.

Сохранить список пользовательских объектов в 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();

Получить список пользовательских объектов из 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
источник
3
Что такое "Тип" там? (в списке Get, 2-я строка).
гангадхары
15

Я знаю, что эта тема немного старая. Но я все равно опубликую это, надеясь, что это может кому-то помочь. Мы можем сохранить поля любого объекта с общими предпочтениями , сериализовав объект в строку. Здесь я использовал GSONдля хранения любого объекта с общими предпочтениями.

Сохранить объект в настройках:

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

Получить объект из предпочтения:

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

Примечание :

Не забудьте добавить compile 'com.google.code.gson:gson:2.6.2'к dependenciesвашему Gradle.

Пример :

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

Обновить:

Как отметил @Sharp_Edge в комментариях, вышеуказанное решение не работает с List.

Небольшая модификация подписи getSavedObjectFromPreference()- от Class<GenericClass> classTypeдо Type classTypeсделает это решение обобщенным. Модифицированная функция подписи,

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

Для вызова,

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

Удачного кодирования!

TPK
источник
1
это было действительно полезно, спасибо. Для всех здесь, кто хочет комментировать ... я должен поместить вызов saveObjectToSharedPreference в onSaveInstanceState? У меня это есть в onSaveInstanceState сейчас, но, поскольку мое приложение собирает данные в режиме реального времени каждые 10 секунд, я время от времени получаю сбой, и объект, который я сохраняю с помощью saveObjectToSharedPreference, теряет некоторые показания. Все мысли приветствуются.
Фрэнк Заппа
эй @FrankZappa, прости, я не совсем понял твою проблему, но здесь ты попробуй использовать commitвместо apply. Это может помочь вам.
tpk
Спасибо. Позвольте мне попытаться объяснить. Мое приложение для Android собирает данные в режиме реального времени примерно каждые 10 секунд. Этот сбор данных не использует объекты, только глобальные переменные и логику. Затем данные затем суммируются и сохраняются в объекте Java. Я использую ваш метод выше для хранения и извлечения моего Java-объекта в / через SharedPreferences, потому что: а) насколько я знаю, я не могу хранить объекты в onSavedInstanceState и б) когда экран вращается, мой объект уничтожается и воссоздается. Поэтому я использую ваш подход SharedPrefs, чтобы при повороте экрана мой объект не терял своих значений. (продолжение)
Фрэнк Заппа
Я поместил вашу подпрограмму saveObjectToSharedPreferences в onSaveInstanceState. Я поместил вашу процедуру getSavedObjectFromPreference в onRestoreInstanceState. Тем не менее, я протестировал и все еще получил один набор пропущенных обновлений объектов из-за поворота экрана. Следовательно, я должен переместить вызов saveObjectToSharedPreferences ближе к моей реальной логике? И наконец, к какому методу относятся и применяются относящиеся?
Фрэнк Заппа
1
@ 2943 Ваше решение выглядит великолепно, но если у меня есть список, например, List<CustomClass>как мне это сделать? getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class)не принимает List<CustomClass>.class:(
Sharp Edge
6

Лучше создать глобальный Constantsкласс для сохранения ключа или переменных для извлечения или сохранения данных.

Для сохранения данных вызовите этот метод, чтобы сохранить данные отовсюду.

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

Используйте это, чтобы получить данные.

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

и метод что-то вроде этого сделает свое дело

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;
}
Адил Соомро
источник
Чтобы вернуть данные, что я передаю как 'variable' и 'defaultValue'?
Алекс
Никогда не создавайте класс Constants. Это делает ваш код сильно связанным и разбросанным одновременно.
Miha_x64
5

Попробуйте этот лучший способ:

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

}

Напишите значение:

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

И получить значение, используя:

String name= PreferenceConnector.readString(this, PreferenceConnector.name, "");
Гириш Патель
источник
2
Какое это имеет отношение к сохранению объекта в SharedPreferences на Android?
Игорь Ганапольский
Дополнительную информацию о работе с Sharedpreferences можно найти на stackoverflow.com/a/2614771/1815624 к сведению, которое вы можете использовать return PreferenceManager.getDefaultSharedPreferences(context);вместоreturn context.getSharedPreferences(PREF_NAME, MODE);
CrandellWS
3

prefsEditorПосле этого вы не указали, что вы делаете с объектом, но чтобы сохранить данные о предпочтениях, вам также необходимо использовать:

prefsEditor.commit();
RivieraKid
источник
2

Смотрите здесь, это может помочь вам:

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
Не могли бы вы объяснить код немного подробнее, поскольку в настоящее время он представляет собой просто «кучу кода».
Вернер
1

Другой способ сохранить и восстановить объект из общих настроек Android без использования формата 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

Вы можете сохранить объект в настройках без использования какой-либо библиотеки, в первую очередь ваш класс объекта должен реализовать 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;
}

}

Затем вы можете легко использовать эти два метода для преобразования объекта в строку и строки в объект:

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

Сохранить:

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

Читать

String value= mPrefs.getString("MyObject", "");
MyObject obj = stringToObjectS(value);
farhad.kargaran
источник
Вы можете избежать кодирования Base64 и экранирования XML, просто записав эти байты в отдельный файл.
Miha_x64
1

Шаг 1: Скопируйте и вставьте эти две функции в ваш файл 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);
    }

Шаг 2: сохранить использование:

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

извлечь использование:

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

Вы можете установить разные общие настройки, используя разные имена ключей, такие как:

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

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

setDefaults("key3","pqr",this);
Вирадж Сингх
источник
1

Если вы хотите сохранить весь объект, который вы получите в ответ, он может достичь чего-то вроде:

Сначала создайте метод, который преобразует ваш JSON в строку в вашем классе утилит, как показано ниже.

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

Затем в классе общих настроек.

 public void storeLoginResponse(yourResponseClass objName) {

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

а затем создать метод для 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();
    }
}

Затем просто вызовите метод First, когда вы получите ответ, и второй, когда вам нужно получить данные из общих настроек, например

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

вот и все.

Надеюсь, это поможет вам.

Happy Coding();

Naresh
источник
1

У меня возникли проблемы с использованием принятого ответа для доступа к данным общих предпочтений во всех действиях. На этих шагах вы даете getSharedPreferences имя для доступа к нему.

Добавьте следующую зависимость в файл build.gradel (Module: app) под Gradle Scripts:

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

Сохранить:

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

Получить в другой деятельности:

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'

надеюсь, это поможет вам :)

user7168064
источник
1

Вот пример использования делегированных свойств Kotlin, который я взял отсюда , но расширил его и предоставляет простой механизм получения / установки свойств SharedPreference.

Для String, Int, Long, Floatили Boolean, он использует стандартный SharePreference геттер (ы) и сеттер (ы). Однако для всех других классов данных он использует GSON для сериализации в a Stringдля установщика. Затем десериализуется в объект данных для получения.

Как и в других решениях, для этого требуется добавить GSON в качестве зависимости в ваш файл Gradle:

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

Вот пример простого класса данных, который мы хотели бы сохранить и сохранить в SharedPreferences:

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

Вот один класс, который реализует делегаты свойства:

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

Примечание: вам не нужно ничего обновлять в sealed class. Делегированные свойства объекта / Синглтоны UserPreferenceProperty, NullableUserPreferencePropertyи FirstTimeUser.

Чтобы настроить новый объект данных для сохранения / получения из SharedPreferences, теперь просто добавить четыре строки:

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

Наконец, вы можете читать / записывать значения в SharedPreferences, просто используя byключевое слово:

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

Если ваш объект сложный, я бы предложил сериализовать / XML / JSON и сохранить это содержимое на SD-карту. Вы можете найти дополнительную информацию о том, как сохранить во внешнем хранилище здесь: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal

trenpixster
источник
Разве это не требует дополнительного разрешения (SD-карта)?
Ришабх
Да, так и будет, поскольку вы будете записывать на SD-карту.
trenpixster
1
По моему опыту, чем меньше разрешений, необходимых пользователю, тем лучше. SD-карта должна быть второстепенным вариантом, если использование Gson, как указано выше, нецелесообразно.
Ришабх
Да, я тоже согласен с этим; Только если результат JSON достаточно велик, SD-карта должна быть опцией. Это компромисс, я бы сказал.
trenpixster
0

Есть два файла, которые решают все ваши проблемы с разделяемыми настройками

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

теперь вы можете сохранить, удалить или получить как,

-спасти

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

-удалять

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

-получить

 AppPreference.getPreference(context, AppPersistence.keys.USER_ID);
Гаутам Сурани
источник
0

Хранить данные в SharedPreference

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

источник
0

Мой класс утилит для сохранения списка в 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);
    }
}

С помощью

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

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

,
Полный код моих утилит // проверьте, используя пример в коде активности

Фан Ван Линь
источник
0

Я использовал Джексон для хранения своих объектов ( Джексон ).

Добавлена ​​библиотека Джексона в Gradle:

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'

Мой тестовый класс:

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

Объект Java в JSON:

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

Сохраните его в общих настройках:

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

Восстановите его из общих настроек:

ObjectMapper objectMapper = new ObjectMapper();
Car car = objectMapper.readValue(preferences.car().get(), Car.class);
Мануэль Шмитцбергер
источник