SharedPreferences可以保存序列化對象的管理工具

事先聲明辖试,本文涉及的代碼辜王,是參考網(wǎng)上大神的代碼,加以總結的結果罐孝。因為時間比較久呐馆,無法確定具體的出處,總之要感謝大神們的分享莲兢。

言歸正傳汹来,我們都知道,SharedPreferences只能保存幾種基本的數(shù)據(jù)類型:

public interface Editor {
    SharedPreferences.Editor putString(String var1, String var2);

    SharedPreferences.Editor putStringSet(String var1, Set<String> var2);

    SharedPreferences.Editor putInt(String var1, int var2);

    SharedPreferences.Editor putLong(String var1, long var2);

    SharedPreferences.Editor putFloat(String var1, float var2);

    SharedPreferences.Editor putBoolean(String var1, boolean var2);

    SharedPreferences.Editor remove(String var1);

    SharedPreferences.Editor clear();

    boolean commit();

    void apply();
}

但是改艇,我們實際開發(fā)中收班,往往需要保存一下簡單實體信息(比如登錄用戶的基本信息),內容太少谒兄,沒有必要使用數(shù)據(jù)庫存儲摔桦,而SharedPreferences的簡單類型有不能滿足我們的需求。這時候我們通常需要將需要保存的對象承疲,轉化為字符串邻耕,然后通過SharedPreferences,進行保存燕鸽。
當然具體方法不唯一赊豌,比如講對象轉化為json字符串進行保存,我們這里介紹的是將對象轉換為ObjectOutputStream流绵咱,然后Base64將流轉化為字符串進行保存。

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = null;
    String objectStr = "";
    try {
        oos = new ObjectOutputStream(baos);
        oos.writeObject(object);
        // 將對象放到OutputStream中
        // 將對象轉換成byte數(shù)組,并將其進行base64編碼
        objectStr = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));
        baos.close();
        oos.close();
    } catch (IOException e) {
        e.printStackTrace();
        return;
    }

下面是具體的工具類SPUtil :

    import android.content.Context;
    import android.content.SharedPreferences;
    import android.preference.PreferenceManager;
    import android.util.Base64;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Map;
    
    /**
     * Author:Henry
     * Date:2017/12/21
     * Email:Heneymark@gmail.com.
     * Description: SharedPreferences 統(tǒng)一管理類
     */
    public class SPUtil {
    
        /**
         * 保存到手機的文件
         */
        public final static String FILE_NAME = "share_date";
    
    
        /**
         * 保存數(shù)據(jù)的方法悲伶,將不同類型的數(shù)據(jù)保存到文件中
         *
         * @param context
         * @param key
         * @param object
         */
        public static void put(Context context, String key, Object object) {
    
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
    
            if (object instanceof String) {
                editor.putString(key, (String) object);
            } else if (object instanceof Integer) {
                editor.putInt(key, (Integer) object);
            } else if (object instanceof Boolean) {
                editor.putBoolean(key, (Boolean) object);
            } else if (object instanceof Float) {
                editor.putFloat(key, (Float) object);
            } else if (object instanceof Long) {
                editor.putLong(key, (Long) object);
            } else {
                editor.putString(key, object.toString());
            }
    
            SharedPreferencesCompat.apply(editor);
        }
    
        /**
         * 獲取保存的序列化的實體
         *
         * @param context
         * @param key
         * @return
         */
        public static Object getSerializableEntity(Context context, String key) {
            SharedPreferences sharePre = PreferenceManager.getDefaultSharedPreferences(context);
            try {
                String wordBase64 = sharePre.getString(key, "");
                // 將base64格式字符串還原成byte數(shù)組
                if (wordBase64 == null || wordBase64.equals("")) { // 不可少艾恼,否則在下面會報java.io
                    // .StreamCorruptedException
                    return null;
                }
                byte[] objBytes = Base64.decode(wordBase64.getBytes(), Base64.DEFAULT);
                ByteArrayInputStream bais = new ByteArrayInputStream(objBytes);
                ObjectInputStream ois = new ObjectInputStream(bais);
                // 將byte數(shù)組轉換成product對象
                Object obj = ois.readObject();
                bais.close();
                ois.close();
                return obj;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
        /**
         * 保存序列號的實體類
         *
         * @param context
         * @param key
         * @param object
         */
        public static void putSerializableEntity(Context context, String key, Serializable object) {
    
            SharedPreferences share = PreferenceManager.getDefaultSharedPreferences(context);
            if (object == null) {
                SharedPreferences.Editor editor = share.edit().remove(key);
                return;
            }
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = null;
            String objectStr = "";
            try {
                oos = new ObjectOutputStream(baos);
                oos.writeObject(object);
                // 將對象放到OutputStream中
                // 將對象轉換成byte數(shù)組,并將其進行base64編碼
                objectStr = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));
                baos.close();
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
            SharedPreferences.Editor editor = share.edit();
            // 將編碼后的字符串寫到base64.xml文件中
            editor.putString(key, objectStr);
            SharedPreferencesCompat.apply(editor);
        }
    
    
        /**
         * 得到保存數(shù)據(jù)的方法麸锉,根據(jù)默認值得到保存的數(shù)據(jù)的具體類型钠绍,然后調用相對于的方法獲取值
         *
         * @param context
         * @param key
         * @param defaultObject
         * @return
         */
        public static Object get(Context context, String key, Object defaultObject) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                    Context.MODE_PRIVATE);
    
            if (defaultObject instanceof String) {
                return sp.getString(key, (String) defaultObject);
            } else if (defaultObject instanceof Integer) {
                return sp.getInt(key, (Integer) defaultObject);
            } else if (defaultObject instanceof Boolean) {
                return sp.getBoolean(key, (Boolean) defaultObject);
            } else if (defaultObject instanceof Float) {
                return sp.getFloat(key, (Float) defaultObject);
            } else if (defaultObject instanceof Long) {
                return sp.getLong(key, (Long) defaultObject);
            }
    
            return null;
        }
    
        /**
         * 移除某個key值已經對應的值
         *
         * @param context
         * @param key
         */
        public static void remove(Context context, String key) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                    Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            editor.remove(key);
            SharedPreferencesCompat.apply(editor);
        }
    
        /**
         * 清除所有數(shù)據(jù)
         *
         * @param context
         */
        public static void clear(Context context) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                    Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            editor.clear();
            SharedPreferencesCompat.apply(editor);
        }
    
        /**
         * 查詢某個key是否已經存在
         *
         * @param context
         * @param key
         * @return
         */
        public static boolean contains(Context context, String key) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                    Context.MODE_PRIVATE);
            return sp.contains(key);
        }
    
        /**
         * 返回所有的鍵值對
         *
         * @param context
         * @return
         */
        public static Map<String, ?> getAll(Context context) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                    Context.MODE_PRIVATE);
            return sp.getAll();
        }
    
    
        /**
         * 創(chuàng)建一個解決SharedPreferencesCompat.apply方法的一個兼容類
         */
        static class SharedPreferencesCompat {
            private static final Method sApplyMethod = findApplyMethod();
    
            /**
             * 反射查找apply的方法
             *
             * @return
             */
            @SuppressWarnings({"unchecked", "rawtypes"})
            private static Method findApplyMethod() {
                try {
                    Class clz = SharedPreferences.Editor.class;
                    return clz.getMethod("apply");
                } catch (NoSuchMethodException e) {
                }
                return null;
            }
    
            /**
             * 如果找到則使用apply執(zhí)行,否則使用commit
             *
             * @param editor
             */
            public static void apply(SharedPreferences.Editor editor) {
                try {
                    if (sApplyMethod != null) {
                        sApplyMethod.invoke(editor);
                        return;
                    }
                } catch (IllegalArgumentException e) {
                } catch (IllegalAccessException e) {
                } catch (InvocationTargetException e) {
                }
                editor.commit();
            }
        }
    }

這里我是將普通類型的存儲與對象的存儲分來花沉,當然也可以直接放到put方法里柳爽,直接加個判斷就行了。

注意:
1.存儲對象必須序列化碱屁;
2.方法中涉及Context的傳值磷脯,盡量使用Application的Context,防止內存泄漏娩脾。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末赵誓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子柿赊,更是在濱河造成了極大的恐慌俩功,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碰声,死亡現(xiàn)場離奇詭異诡蜓,居然都是意外死亡,警方通過查閱死者的電腦和手機胰挑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門蔓罚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洽腺,你說我怎么就攤上這事脚粟。” “怎么了蘸朋?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵核无,是天一觀的道長。 經常有香客問我藕坯,道長团南,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任炼彪,我火速辦了婚禮吐根,結果婚禮上,老公的妹妹穿的比我還像新娘辐马。我一直安慰自己拷橘,他們只是感情好,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冗疮,像睡著了一般萄唇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上术幔,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天另萤,我揣著相機與錄音,去河邊找鬼诅挑。 笑死四敞,一個胖子當著我的面吹牛,可吹牛的內容都是我干的拔妥。 我是一名探鬼主播忿危,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼毒嫡!你這毒婦竟也來了癌蚁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤兜畸,失蹤者是張志新(化名)和其女友劉穎努释,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咬摇,經...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡伐蒂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了肛鹏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逸邦。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖在扰,靈堂內的尸體忽然破棺而出缕减,到底是詐尸還是另有隱情,我是刑警寧澤芒珠,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布桥狡,位于F島的核電站,受9級特大地震影響皱卓,放射性物質發(fā)生泄漏裹芝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一娜汁、第九天 我趴在偏房一處隱蔽的房頂上張望嫂易。 院中可真熱鬧,春花似錦掐禁、人聲如沸怜械。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缕允。三九已至融虽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間灼芭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工般又, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留彼绷,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓茴迁,卻偏偏與公主長得像寄悯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子堕义,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內容

  • 第5章 引用類型(返回首頁) 本章內容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學一百閱讀 3,233評論 0 4
  • 1. Java基礎部分 基礎部分的順序:基本語法猜旬,類相關的語法,內部類的語法倦卖,繼承相關的語法洒擦,異常的語法,線程的語...
    子非魚_t_閱讀 31,623評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理怕膛,服務發(fā)現(xiàn)熟嫩,斷路器,智...
    卡卡羅2017閱讀 134,652評論 18 139
  • 每每聽到別人搬家褐捻,內心總會升騰出莫須有的小小的羨慕掸茅,以為那將是一個無比美妙的過程,伴隨搬家柠逞,總會舍去一些舊物新增一...
    柳二白閱讀 473評論 1 1
  • 藍夫原創(chuàng)昧狮,轉載請聯(lián)系授權。 一茶易苦易甜易此生板壮,一禪靜心靜念靜欲靜繁世逗鸣。拋俗拋怨拋金拋祿,生有聚个束,死易散慕购。此生何懼...
    藍笑笑閱讀 254評論 0 0