SharePreference技巧之保存一個(gè)對(duì)象

在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);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 整體Retrofit內(nèi)容如下: 1、Retrofit解析1之前哨站——理解RESTful 2、Retrofit解析...
    隔壁老李頭閱讀 4,810評(píng)論 2 12
  • 在經(jīng)過一次沒有準(zhǔn)備的面試后,發(fā)現(xiàn)自己雖然寫了兩年的android代碼,基礎(chǔ)知識(shí)卻忘的差不多了。這是程序員的大忌,沒...
    猿來如癡閱讀 3,141評(píng)論 3 10
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,355評(píng)論 25 708
  • 對(duì)象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法,而不是構(gòu)造函數(shù)創(chuàng)建對(duì)象:僅僅是創(chuàng)建對(duì)象的方法,并非Fa...
    孫小磊閱讀 2,186評(píng)論 0 3
  • 南京,南京。被江流劃為南北的都城,被歷史寫成故事,被故事活出現(xiàn)實(shí)。 我羨慕著那些在這里安頓自己的人,把生活印在石頭...
    關(guān)于叁件事閱讀 402評(píng)論 0 0

友情鏈接更多精彩內(nèi)容