Як Android SharedPreferences зберігає / зберігає об’єкт


216

Нам потрібно отримати об’єкти користувачів у багатьох місцях, які містять багато полів. Після входу я хочу зберегти / зберегти ці об’єкти користувача. Як ми можемо реалізувати такий сценарій?

Я не можу зберігати його так:

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

який тип даних ви хочете зберігати?
ilango j


Що ви мали на увазі під «« та виконавчим об’єктом »? Будь ласка, перевірте свою граматику перед публікацією в StackOverflow.
ІгорГанапольський

Ви можете використовувати цю бібліотеку, яка має багато можливостей ... github.com/moinkhan-in/PreferenceSpider
Moinkhan

Відповіді:


548

Ви можете використовувати 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);
cesarferreira

Вам потрібні всі 3 банки? У цьому посиланні є 3 з них. . .
coolcool1994

3
Правильна URL-адреса для завантаження баночки: search.maven.org/…
Shajeel Afzal

2
Це проблема з круговою посиланням , що призводить до StackOverflowException XD Детальніше тут stackoverflow.com/questions/10209959 / ...
phuwin

1
@rozina так Gson - це краще. Перш за все, щоб використовувати серіалізацію, об’єкт і кожен об'єкт всередині нього повинні реалізувати інтерфейс серіалізації. Це не потрібно для gson. gson також чудово працює, коли ваш об’єкт - це список об’єктів.
Neville Nazerane

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

3
Що там "Тип"? (у списку Отримати, 2-й рядок).
gangadhars

15

Я знаю, що ця нитка трохи стара. Але я все одно опублікую це, сподіваючись, що це може комусь допомогти. Ми можемо зберігати поля будь-якого об'єкта для спільних уподобань шляхом серіалізації об'єкта до String. Тут я використовував 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своєї студії.

Приклад :

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

Щасливе кодування!


1
це було дуже корисно дякую. Для когось тут, хто цікавиться прокоментувати ... чи варто мені поставити виклик saveObjectToSharedPreference в onSaveInstanceState? У мене це є в OnSaveInstanceState зараз, але, враховуючи, що моя програма збирає дані в реальному часі кожні 10 секунд, я отримую ікоту раз у раз, і об'єкт, який я зберігаю за допомогою saveObjectToSharedPreference, втрачає деякі читання. Всі думки вітаються.
Френк Заппа

Ей @FrankZappa, пробач, я не повністю розумію твою проблему, але ось ти підеш, спробуй використовувати commitзамість apply. Це може вам допомогти.
tpk

Дякую. Дозвольте спробувати пояснити. Мій додаток Android збирає дані в режимі реального часу приблизно кожні 10 секунд. Цей збір даних не використовує ніяких об'єктів, а лише глобальні змінні та логіку. Далі дані потім підсумовуються та зберігаються в об’єкті Java. Я використовую ваш метод вище для зберігання та отримання мого об'єкта Java в / через SharedPreferences, оскільки а) наскільки мені відомо, я не можу зберігати об'єкти в OnSavedInstanceState і b) коли екран обертається, мій об’єкт знищується та відтворюється. Тому я використовую ваш підхід SharedPrefs, тому при поверненні екрана мій об’єкт не втрачає своїх значень. (продовж ..)
Френк Заппа

Я помістив вашу процедуру saveObjectToSharedPreferences в onSaveInstanceState. Я помістив вашу процедуру getSavedObjectFromPreference в onRestoreInstanceState. Однак я протестував і все-таки отримав один набір пропущених оновлень об’єктів через обертання екрана. Тому я повинен перенести виклик на saveObjectToSharedPreferences ближче до моєї фактичної логіки? Нарешті, до якого методу належить скористатися та застосувати?
Френк Заппа

1
@ 2943 Рішення у вас виглядає чудово, але якщо у мене є список, наприклад, List<CustomClass>як мені це зробити? getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class)не приймає List<CustomClass>.class:(
Різкий край

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

Щоб повернути дані, що я передаю як "змінну" та "за замовчуванням"?
Олексій

Ніколи не створюйте клас Константи. Це робить ваш код сильно сполученим і розкиданим одночасно.
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();

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

Інший спосіб збереження та відновлення об’єкта з андроїд-спільних налаштувань без використання формату 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);

Ви можете уникнути кодування 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 в рядок вашого класу util, як показано нижче.

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

Тоді просто зателефонуйте Перший метод, коли ви отримаєте відповідь, а другий, коли вам потрібно отримати дані, такі як налаштування спільного доступу

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

це все.

Сподіваюся, це допоможе вам.

Happy Coding();


1

У мене виникли проблеми з використанням прийнятої відповіді для доступу до даних Спільних налаштувань для всіх видів діяльності. На цих кроках ви даєте ім'я getSharedPreferences, щоб отримати доступ до нього.

Додайте таку залежність у файл build.gradel (Модуль: додаток) у розділі Сценарії Gradle:

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'

сподіваюся, що це допоможе вам :)


1

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

Для String, Int, Long, Floatабо Boolean, він використовує стандартний SharePreference геттер (и) і сетер (и). Однак для всіх інших класів даних використовується GSON для серіалізації до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

Якщо ваш Об'єкт складний, я б запропонував його Serialize / XML / JSON і збереже цей вміст на SD-карті. Додаткову інформацію про збереження до зовнішнього сховища ви можете знайти тут: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal


Хіба для цього не потрібен додатковий дозвіл (SD-карта)?
rishabh

Так, це буде з моменту запису на SD-карту.
тренпіксстер

1
З мого досвіду, чим менше дозволів, необхідних користувачеві, тим краще. SD-карта повинна бути другорядним вибором, якщо використання Gson, як було зазначено вище, не є можливим варіантом.
rishabh

Так, я теж згоден з цим; Тільки якщо результат JSON достатньо великий, SD-карта повинна бути опцією. Я б сказав, що це компроміс.
тренпіксстер

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

Я використовував Джексона для зберігання своїх предметів ( jackson ).

До 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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.