我正在开发一个用于在SharedPreferences中存储数据的实用程序类。直到现在,我能够创建一个通用函数来存储和检索String,int和boolean。是否存在存储和检索对象集合的通用方法?
答案 0 :(得分:2)
没有直接的方式,只有两种间接方式:
<强> 1。使用GSON。
public static boolean saveObjectToPrefs(String prefKey, Object object, Context context) {
SharedPreferences.Editor editor = getSharedPreferences(context).edit();
try {
Gson gson = new Gson();
String json = gson.toJson(object);
editor.putString(prefKey, json);
editor.apply();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
这里的通用应该实现 Serializable 接口。
要检索对象,请创建如下方法:
public static <T> T getObjectFromPrefs(String prefKey, Class<T> type, Context context) {
String json = getSharedPreferences(context).getString(prefKey, null);
if (json != null) {
try {
Gson gson = new Gson();
T result = gson.fromJson(json, type);
return result;
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
你可以像集合一样调用这个方法:
PrefUtils.getObjectFromPrefsByType(PREF_KEY_USERS, new TypeToken<ArrayList<User>>() {
}.getType(), context);
对于您可以执行的普通对象:
PrefUtils.getObjectFromPrefsByType(PREF_KEY_USER, User.class, context);
<强> 2。编写自定义序列化程序和反序列化程序
我通常更喜欢这种方法,因为我不必为它包含一个库。
这是自定义序列化器/反序列化器实现:
public class ObjectSerializer {
public static String serialize(Serializable obj){
if (obj == null) return "";
try {
ByteArrayOutputStream serialObj = new ByteArrayOutputStream();
ObjectOutputStream objStream = new ObjectOutputStream(serialObj);
objStream.writeObject(obj);
objStream.close();
return encodeBytes(serialObj.toByteArray());
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Object deserialize(String str) {
if (str == null || str.length() == 0) return null;
try {
ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str));
ObjectInputStream objStream = new ObjectInputStream(serialObj);
return objStream.readObject();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String encodeBytes(byte[] bytes) {
StringBuilder strBuf = new StringBuilder();
for (Byte b: bytes) {
strBuf.append((char) (((b >> 4) & 0xF) + ((int) 'a')));
strBuf.append((char) (((b) & 0xF) + ((int) 'a')));
}
return strBuf.toString();
}
public static byte[] decodeBytes(String str) {
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < str.length(); i+=2) {
char c = str.charAt(i);
bytes[i/2] = (byte) ((c - 'a') << 4);
c = str.charAt(i+1);
bytes[i/2] += (c - 'a');
}
return bytes;
}
}
现在,在PrefUtils.java中,您可以使用以下方法:
public static void saveUser(Context context, User user) {
getSharedPreferences(context)
.edit()
.putString(PREF_KEY_USER, ObjectSerializer.serialize(user))
.apply();
}
要检索对象,您可以使用以下方法:
public static User getUser(Context context) {
String serializedUser = getSharedPreferences(context).getString(PREF_KEY_USER, "");
return ((User) ObjectSerializer.deserialize(serializedUser));
}
再次,User类必须是Serializable。此外,不要忘记显式转换,因为ObjectSerializer.deserialize(String str)方法返回类型为对象的对象,而不是您序列化的类。另外,请注意空值。
答案 1 :(得分:0)
是否存在存储和检索对象集合的通用方法?
不,截至目前,没有通用方法。您可以使用以下方法:
putBoolean(String key,boolean value)
putFloat(字符串键,浮点值)
putInt(String key,int value)
putLong(字符串键,长值)
putString(String key,String value)
putStringSet(字符串键,设置值)
这就是SharedPreferences
所能做的一切。如果要存储任何通用的东西,可以尝试序列化对象并将其作为String添加到SharedPreferences。 About Serialization
答案 2 :(得分:0)
我花了很多时间玩这个问题。因为我和iPhone一起工作,怎么能保存anyObjects(那是什么??):)
我已经确定了两个解决方案。如果我正在存储具有短期使用的缓存,我将一个abitrary对象包装为Parceler与Parceler(https://github.com/johncarl81/parceler)。
如果我需要应用程序用来保存用户操作的持久数据,我用GSON包装任何abitrary对象,并将其保存到磁盘。这样我仍然可以使用更多字段更新应用程序,并且仍然使用来自GSON对象的数据,因为它处理空值字段。 (https://github.com/google/gson)