在Android中我們經(jīng)常需要持久化保存數(shù)據(jù)呛哟,這時(shí)可以使用文件苞俘,SharePreference癣诱,以及SQLite等计维。如果我想保存一個(gè)對(duì)象呢?有些人會(huì)立馬想到用orm框架撕予,但是我可能不想依賴這個(gè)框架鲫惶。實(shí)際上如果數(shù)據(jù)量不大,用SharePreference可能會(huì)更適合实抡。我們完全可以自己實(shí)現(xiàn)一個(gè)SharePreference版的持久化保存對(duì)象的工具類剑按。
直接看代碼
public class SpUtils {
private static final String DEFAULT_SP_NAME = "default_sp";
public static <T> T getObject(Context context, Class<T> clazz) {
String key = getKey(clazz);
String json = getString(context, key, null);
if (TextUtils.isEmpty(json)) {
return null;
}
try {
Gson gson = new Gson();
return gson.fromJson(json, clazz);
} catch (Exception e) {
return null;
}
}
public static void putObject(Context context, Object object) {
String key = getKey(object.getClass());
Gson gson = new Gson();
String json = gson.toJson(object);
putString(context, key, json);
}
public static void removeObject(Context context, Class<?> clazz){
remove(context, getKey(clazz));
}
public static String getKey(Class<?> clazz) {
return clazz.getName();
}
public static void remove(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor edit = sp.edit();
edit.remove(key);
edit.commit();
}
public static void putString(Context context, String key, String value) {
SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor edit = sp.edit();
edit.putString(key, value);
edit.commit();
}
public static String getString(Context context, String key, String defValue) {
SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
return sp.getString(key, defValue);
}
}
- putObject()方法中,我們以對(duì)象的類名字作為key澜术,以對(duì)象的json字符串作為value保存到SharePreference中。
- getObject()方法猬腰,我們先獲取類的名字鸟废,再將它作為key,然后從SharePreference中獲取對(duì)應(yīng)的字符串姑荷,然后通過Gson將json字符串轉(zhuǎn)化為對(duì)象盒延。
到目前為止,看起來還不錯(cuò)鼠冕,但是聰明的你可能會(huì)發(fā)現(xiàn)添寺,如果我要保存的類是一個(gè)泛型呢,比如List<Person>
懈费,用上面的方法肯定時(shí)不行了计露,因?yàn)榉盒蜁?huì)被擦除,List<String>
和List<Person>
都是同一個(gè)類憎乙。關(guān)于泛型擦除可參考:Java 的泛型擦除和運(yùn)行時(shí)泛型信息獲取票罐。
那么對(duì)于泛型該如何處理呢?
回顧用Gson解析泛型類時(shí)泞边,我們可能寫過類似下面的代碼:
String json = result;
Gson gson = new Gson();
Type type = new TypeToken<List<Person>>() {/*注意這里有個(gè)大括號(hào)*/}.getType());
List<Person> list = gson.fromJson(json, type);
這里用TypeToken去獲取泛型的信息该押。
Ok,我們已經(jīng)有思路了
public class SpUtils {
// 獲取一個(gè)泛型的對(duì)象
public static <T> T getObject(Context context, Type type) {
String key = getKey(type);
String json = getString(context, key, null);
if (TextUtils.isEmpty(json)) {
return null;
}
try {
Gson gson = new Gson();
return gson.fromJson(json, type);
} catch (Exception e) {
return null;
}
}
// 保存一個(gè)泛型的對(duì)象
public static void putObject(Context context, Object object, Type type) {
String key = getKey(type);
Gson gson = new Gson();
String json = gson.toJson(object);
putString(context, key, json);
}
public static void removeObject(Context context, Type type) {
remove(context, getKey(type));
}
public static String getKey(Type type) {
return type.toString();
}
}
- getObject()方法中阵谚,使用Type參數(shù)代替原來的Class
- putObject()方法中蚕礼,新增一個(gè)Type參數(shù)烟具,用來獲取SharePreference中的key。
使用也不難:
List<Person> list = new ArrayList<>();
Person p = new Person(20, "張三1");
list.add(p);
p = new Person(20, "張三2");
list.add(p);
// 保存一個(gè)泛型對(duì)象
SpUtils.putObject(context, list,
new TypeToken<List<Person>>() { }.getType());
// 獲取一個(gè)泛型對(duì)象
List<Person> list2 = SpUtils.getObject(context,
new TypeToken<List<Person>>() { }.getType());
完整代碼如下:
import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
import com.google.gson.Gson;
import java.lang.reflect.Type;
public class SpUtils {
private static final String DEFAULT_SP_NAME = "default_sp";
// 通過類名字去獲取一個(gè)對(duì)象
public static <T> T getObject(Context context, Class<T> clazz) {
String key = getKey(clazz);
String json = getString(context, key, null);
if (TextUtils.isEmpty(json)) {
return null;
}
try {
Gson gson = new Gson();
return gson.fromJson(json, clazz);
} catch (Exception e) {
return null;
}
}
// 通過Type去獲取一個(gè)泛型對(duì)象
public static <T> T getObject(Context context, Type type) {
String key = getKey(type);
String json = getString(context, key, null);
if (TextUtils.isEmpty(json)) {
return null;
}
try {
Gson gson = new Gson();
return gson.fromJson(json, type);
} catch (Exception e) {
return null;
}
}
/**
* 保存一個(gè)對(duì)象奠蹬,object必須是普通類朝聋,而不是泛型,如果是泛型,請(qǐng)使用 {@link SpUtils#putObject(Context, Object, Type)}
*
* @param context
* @param object
*/
public static void putObject(Context context, Object object) {
String key = getKey(object.getClass());
Gson gson = new Gson();
String json = gson.toJson(object);
putString(context, key, json);
}
/**
* 保存一個(gè)泛型對(duì)象
*
* @param context
* @param object
* @param type 如果你要保存 List<Person> 這個(gè)類, type應(yīng)該 傳入 new TypeToken<List<Person>>() {}.getType()
*/
public static void putObject(Context context, Object object, Type type) {
String key = getKey(type);
Gson gson = new Gson();
String json = gson.toJson(object);
putString(context, key, json);
}
public static void removeObject(Context context, Class<?> clazz) {
remove(context, getKey(clazz));
}
public static void removeObject(Context context, Type type) {
remove(context, getKey(type));
}
public static String getKey(Class<?> clazz) {
return clazz.getName();
}
public static String getKey(Type type) {
return type.toString();
}
public static void remove(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor edit = sp.edit();
edit.remove(key);
edit.commit();
}
public static void putString(Context context, String key, String value) {
SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor edit = sp.edit();
edit.putString(key, value);
edit.commit();
}
public static String getString(Context context, String key, String defValue) {
SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
return sp.getString(key, defValue);
}
}