Android SharedPreferences如何保存/存储对象


216

我们需要在许多地方获取用户对象,其中包含许多字段。登录后,我想保存/存储这些用户对象。我们如何实现这种情况?

我不能这样存储它:

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

您要存储哪种类型的数据?
ilango j 2011年


“〜” 和“执行对象 ” 是什么意思?在StackOverflow上发布之前,请检查语法。
IgorGanapolsky '16

您可以使用具有许多功能的此库... github.com/moinkhan-in/PreferenceSpider
Moinkhan '18

Answers:


548

您可以使用gson.jar将类对象存储到SharedPreferences中。您可以从google-gson下载此jar

或者在您的Gradle文件中添加GSON依赖项:

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
谢谢你,朋友!但是您在Save部分(第3行)中不正确,正确的代码是:String json = gson.toJson(myObject);
cesarferreira

您是否需要全部3个罐子?该链接中有3个。。。
coolcool1994

3
对于下载JAR正确的URL是:search.maven.org/...
Shajeel阿夫扎尔

2
这有一个循环引用的问题,导致StackOverFlowException xD在这里了解更多信息stackoverflow.com/questions/10209959/…–
phuwin

1
@rozina是的,Gson更好。首先要使用序列化,该对象及其内部的每个对象都需要实现序列化接口。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);

3
那里的“类型”是什么?(在“获取列表”的第二行)。
gangadhars 2014年

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您的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)

编码愉快


1
这真的很有帮助,谢谢。对于这里想要评论的任何人...我应该将对saveObjectToSharedPreference的调用放在onSaveInstanceState中吗?我现在将其保存在onSaveInstanceState中,但是,由于我的应用程序每10秒收集一次实时数据,因此我偶尔会打h,并且使用saveObjectToSharedPreference保存的对象会丢失一些读数。欢迎所有想法。
Frank Zappa

嘿@FrankZappa,请原谅我不能完全理解您的问题,但是您可以尝试使用commit代替apply。它可能会帮助您。
tpk

谢谢。让我尝试解释一下。我的Android应用程序大约每10秒实时收集一次数据。该数据收集不使用任何对象,仅使用全局变量和逻辑。接下来,将数据汇总并存储在Java对象中。我使用上面的方法通过/通过SharedPreferences存储和检索我的Java对象,因为a)据我所知我无法在onSavedInstanceState中存储对象,并且b)屏幕旋转时我的对象被破坏并重新创建。因此,我正在使用您的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;
}

为了取回数据,我如何传递“变量”和“默认值”?
亚历克斯(Alex)

永远不要创建Constants类。它使您的代码同时高度耦合和分散。
Miha_x64 '18

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
这与在Android上的SharedPreferences中保存对象有什么关系?
IgorGanapolsky

有关使用Sharedpreferences的更多信息,请参见stackoverflow.com/a/2614771/1815624 注意:您可能想使用它return PreferenceManager.getDefaultSharedPreferences(context);而不是return context.getSharedPreferences(PREF_NAME, MODE);
CrandellWS 2016年

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
您能否再解释一下代码,因为它目前仅代表“一堆代码”。
Werner 2014年

1

另一种无需使用Json格式即可从android sharedpreferences保存和还原对象的方法

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

然后只需在获得响应时调用First方法,然后在需要从共享首选项中获取数据时调用第二方法即可

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

就这样。

希望对您有帮助。

Happy Coding();


1

我无法使用接受的答案来跨活动访问“共享首选项”数据。在这些步骤中,您给getSharedPreferences一个名称来访问它。

在Gradle脚本下的build.gradel(模块:app)文件中添加以下依赖项:

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属性。

StringIntLongFloatBoolean,它使用标准SharePreference吸气剂(S)和setter(一个或多个)。但是,对于所有其他数据类,它使用GSON序列化为String将设置器。然后将其反序列化为该数据对象,以获取该方法。

与其他解决方案类似,这需要在您的gradle文件中添加GSON作为依赖项:

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。委派的属性是对象/单身UserPreferencePropertyNullableUserPreferencePropertyFirstTimeUser

要设置一个新数据对象以从SharedPreferences保存/获取,现在就像添加四行一样简单:

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

最后,只需使用by关键字就可以将值读/写到SharedPreferences :

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


不需要额外的权限(SD卡)吗?
rishabh 2014年

是的,因为您将要写入SD卡,所以可以。
trenpixster 2014年

1
根据我的经验,用户所需的权限越少越好。如果不能使用上述的Gson,则SD卡应该是次要选择。
rishabh 2014年

是的,我也同意这一点。仅当JSON结果足够大时,才可以选择SD卡。我要权衡取舍。
trenpixster 2014年

0

有两个文件解决了您关于sharedpreferences的所有问题

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

我的utils类用于保存列表到 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);


我的utils的完整代码 //使用活动代码中的示例进行检查


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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.