我工作的一个发展中SharedPreferences存储数据的实用工具类。 时至今日,我能够做出一个通用的功能来存储和检索字符串,整数和布尔。 是否有存储和检索对象的集合,一个通用的方法?
Answer 1:
没有直接的方法,但两个间接方式:
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.编写一个自定义的串行器和解串
我通常喜欢这种方法,因为我没有包括它的库。
这是自定义的串行器/解串器implemetation:
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));
}
同样用户类必须是可序列化。 另外,不要忘记明确铸造为ObjectSerializer.deserialize(字符串str)方法返回Object类型的对象,而不是类,你序列化。 另外,取空值的照顾。
Answer 2:
是否有存储和检索对象的集合,一个通用的方法?
否,截至目前,没有通用的方法。 您可以使用以下方法:
putBoolean(String键,布尔值)
putFloat(String键,浮点值)
putInt(String键,int值)
putLong(String键,长值)
putString(String键,字符串值)
putStringSet(String键,设定值)
这就是你可以做SharedPreferences
。 如果你想存储任何通用的,你可以尝试序列化你的对象,并把它作为一个字符串SharedPreferences。 关于序列化
Answer 3:
我已经花了大量的时间与这个问题打。 由于我使用iPhone的人的工作如何能够拯救anyObjects(那是什么?):)
我已经在2个解决方案解决。 如果即时通讯存储具有短期使用的高速缓存,我包装一个abitrary物体的方式与一个Parceler Parceable( https://github.com/johncarl81/parceler )。
如果我需要持久数据的应用程序使用,以节省用户的操作,我缠上GSON任何abitrary对象,并将其保存到磁盘。 这样,我还是可以更新多个字段中的应用程序,并且仍然使用来自GSON对象中的数据,因为它处理空值字段。 ( https://github.com/google/gson )