【Android】數(shù)據(jù)存儲(一) SharedPreferences詳解

SharedPreferences介紹

在Android開發(fā)中件缸,經(jīng)常需要將少量簡單類型數(shù)據(jù)保存在本地期犬,如:用戶設置茧痕。這些需要保存的數(shù)據(jù)可能一兩個字符串句葵,像這樣的數(shù)據(jù)一般選擇使用SharedPreferences來保存丹墨。

SharedPreferences:一個輕量級的存儲類廊遍,特別適合用于保存軟件配置參數(shù)。(是用xml文件存放數(shù)據(jù)贩挣,文件存放在/data/data/<package name>/shared_prefs目錄下)

SharedPreferences可以保存的數(shù)據(jù)類型有:int喉前、boolean、float王财、long卵迂、String、StringSet绒净。

使用SharedPreferences存儲和讀取數(shù)據(jù)的步驟

存儲數(shù)據(jù)

保存數(shù)據(jù)一般分為四個步驟:

  1. 使用Activity類的getSharedPreferences方法獲得SharedPreferences對象见咒;
  2. 使用SharedPreferences接口的edit獲得SharedPreferences.Editor對象;
  3. 通過SharedPreferences.Editor接口的putXXX方法保存key-value對挂疆;
  4. 通過過SharedPreferences.Editor接口的commit方法保存key-value對改览。

讀取數(shù)據(jù)

讀取數(shù)據(jù)一般分為兩個步驟:

  1. 使用Activity類的getSharedPreferences方法獲得SharedPreferences對象;
  2. 通過SharedPreferences對象的getXXX方法獲取數(shù)據(jù)缤言;

用到的方法

  • 獲取SharedPreferences對象
    (根據(jù)name查找SharedPreferences宝当,若已經(jīng)存在則獲取,若不存在則創(chuàng)建一個新的)
public abstract SharedPreferences getSharedPreferences (String name, int mode)

參數(shù)
name:命名
mode:模式胆萧,包括
MODE_PRIVATE(只能被自己的應用程序訪問)
MODE_WORLD_READABLE(除了自己訪問外還可以被其它應該程序讀冉裢)
MODE_WORLD_WRITEABLE(除了自己訪問外還可以被其它應該程序讀取和寫入)

若該Activity只需要創(chuàng)建一個SharedPreferences對象的時候,可以使用getPreferences方法鸳碧,不需要為SharedPreferences對象命名,只要傳入?yún)?shù)mode即可

public SharedPreferences getPreferences (int mode)
  • 獲取Editor對象(由SharedPreferences對象調(diào)用)
abstract SharedPreferences.Editor edit()
  • 寫入數(shù)據(jù)(由Editor對象調(diào)用)
//寫入boolean類型的數(shù)據(jù)
abstract SharedPreferences.Editor   putBoolean(String key, boolean value)
//寫入float類型的數(shù)據(jù)
abstract SharedPreferences.Editor   putFloat(String key, float value)
//寫入int類型的數(shù)據(jù)
abstract SharedPreferences.Editor   putInt(String key, int value)
//寫入long類型的數(shù)據(jù)
abstract SharedPreferences.Editor   putLong(String key, long value)
//寫入String類型的數(shù)據(jù)
abstract SharedPreferences.Editor   putString(String key, String value)
//寫入Set<String>類型的數(shù)據(jù)
abstract SharedPreferences.Editor   putStringSet(String key, Set<String> values)

參數(shù)
key:指定數(shù)據(jù)對應的key
value:指定的值

  • 移除指定key的數(shù)據(jù)(由Editor對象調(diào)用)
abstract SharedPreferences.Editor   remove(String key)

參數(shù)
key:指定數(shù)據(jù)的key

  • 清空數(shù)據(jù)(由Editor對象調(diào)用)
abstract SharedPreferences.Editor   clear()
  • 提交數(shù)據(jù)(由Editor對象調(diào)用)
abstract boolean    commit()
  • 讀取數(shù)據(jù)(由SharedPreferences對象調(diào)用)
//讀取所有數(shù)據(jù)
abstract Map<String, ?> getAll()
//讀取的數(shù)據(jù)為boolean類型
abstract boolean    getBoolean(String key, boolean defValue)
//讀取的數(shù)據(jù)為float類型
abstract float  getFloat(String key, float defValue)
//讀取的數(shù)據(jù)為int類型
abstract int    getInt(String key, int defValue)
//讀取的數(shù)據(jù)為long類型
abstract long   getLong(String key, long defValue)
//讀取的數(shù)據(jù)為String類型
abstract String getString(String key, String defValue)
//讀取的數(shù)據(jù)為Set<String>類型
abstract Set<String>    getStringSet(String key, Set<String> defValues)

參數(shù)
key:指定數(shù)據(jù)的key
defValue:當讀取不到指定的數(shù)據(jù)時犬性,使用的默認值defValue

SharedPreferences的使用

看煩了這些方法瞻离?別著急,乒裆,套利,代碼來了

    /**
     * 保存用戶信息
     */
    private void saveUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = userInfo.edit();//獲取Editor
        //得到Editor后,寫入需要保存的數(shù)據(jù)
        editor.putString("username", "一只貓的涵養(yǎng)");
        editor.putInt("age", 20);
        editor.commit();//提交修改
        Log.i(TAG, "保存用戶信息成功");
    }
    /**
     * 讀取用戶信息
     */
    private void getUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        String username = userInfo.getString("username", null);//讀取username
        int age = userInfo.getInt("age", 0);//讀取age
        Log.i(TAG, "讀取用戶信息");
        Log.i(TAG, "username:" + username + "鹤耍, age:" + age);
    }
    /**
     * 移除年齡信數(shù)據(jù)
     */
    private void removeUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = userInfo.edit();//獲取Editor
        editor.remove("age");
        editor.commit();
        Log.i(TAG, "移除年齡數(shù)據(jù)");
    }

    /**
     * 清空數(shù)據(jù)
     */
    private void clearUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = userInfo.edit();//獲取Editor
        editor.clear();
        editor.commit();
        Log.i(TAG, "清空數(shù)據(jù)");
    }

這里將SharedPreferences簡單的用法都列舉了出來肉迫。

api中還注冊和注銷SharedPreferences被編輯時的監(jiān)聽

        SharedPreferences.OnSharedPreferenceChangeListener changeListener = new OnSharedPreferenceChangeListener() {
            @Override
            public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
                //preferences被 編輯的SharedPreferences實例
                //該SharedPreferences中被編輯的條目所對應的key
            }
        };
        //userInfo注冊監(jiān)聽事件
        userInfo.registerOnSharedPreferenceChangeListener(changeListener);
        //userInfo注銷監(jiān)聽事件
        userInfo.unregisterOnSharedPreferenceChangeListener(changeListener);

性能

  • ShredPreferences是單例對象,第一次打開后稿黄,之后獲取都無需創(chuàng)建喊衫,速度很快。
  • 當?shù)谝淮潍@取數(shù)據(jù)后杆怕,數(shù)據(jù)會被加載到一個緩存的Map中族购,之后的讀取都會非晨翘埃快。
  • 當由于是XML<->Map的存儲方式寝杖,所以违施,數(shù)據(jù)越大,操作越慢瑟幕,get磕蒲、commit、apply只盹、remove辣往、clear都會受影響,所以盡量把數(shù)據(jù)按功能拆分成若干份鹿霸。

Tips

  • tip 1
    這里的用到的:
getSharedPreferences (String name, int mode)
getPreferences (int mode) 
MODE_PRIVATE

都是在Acitivty中執(zhí)行的排吴。若不在Activity中,請使用

context.getSharedPreferences (String name, int mode)
context.getPreferences (int mode)
Conetxt.MODE_PRIVATE 
  • tip 2
    所保存的SharedPreferences數(shù)據(jù)將一直存在懦鼠,除非被覆蓋钻哩、移除、清空或文件被刪除肛冶。
    (SharedPreferences保存的數(shù)據(jù)會隨著應用的卸載而被刪除)
  • tip 3
    同時執(zhí)行這兩句代碼的時候街氢,第一行代碼所寫的內(nèi)容會被第二行代碼取代。
editor.putInt("age", 20);
//覆蓋key為age的數(shù)據(jù)睦袖,得到的結(jié)果:age = 32
editor.putInt("age", 32);
editor.putString("age", "20");
//覆蓋key為age的數(shù)據(jù)珊肃,得到的結(jié)果:age = 32 (int類型)
editor.putInt("age", 32);
  • tip 4
    執(zhí)行以下代碼會出現(xiàn)異常。
    (指定key所保存的類型和讀取時的類型不同)
editor.putInt("age", 32);//保存為int類型
String age = userInfo.getString("age", "null");//讀取時為String類型馅笙,出現(xiàn)異常
  • tip 5
    在這些動作之后伦乔,記得commit
editor.putInt("age", 20);//寫入操作
editor.remove("age");   //移除操作
editor.clear();     //清空操作
editor.commit();//記得commit

附:源代碼

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
/**
 * SharedPreferences用法 測試Activity
 * @author Gavin
 *
 */
public class MainActivity extends Activity {
    private static final String TAG = "SharedPreferencesTest";
    /**
     * 保存數(shù)據(jù)SharedPreferences文件的名字
     */
    private final String PREFS_NAME = "MyPrefsFile";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        saveUserInfo();
        getUserInfo();
        removeUserInfo();
        getUserInfo();
        clearUserInfo();
        getUserInfo();
    }
    
    /**
     * 保存用戶信息
     */
    private void saveUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        SharedPreferences.OnSharedPreferenceChangeListener changeListener = new OnSharedPreferenceChangeListener() {
            
            @Override
            public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
                //preferences被 編輯的SharedPreferences實例
                //該SharedPreferences中被編輯的條目所對應的key
            }
        };
        //userInfo注冊監(jiān)聽事件
        userInfo.registerOnSharedPreferenceChangeListener(changeListener);
        SharedPreferences.Editor editor = userInfo.edit();//獲取Editor
        //得到Editor后,寫入需要保存的數(shù)據(jù)
        editor.putString("username", "一只貓的涵養(yǎng)");
        editor.putInt("age", 20);
        editor.commit();//提交修改
        Log.i(TAG, "保存用戶信息成功");
    }

    /**
     * 讀取用戶信息
     */
    private void getUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        String username = userInfo.getString("username", null);//讀取username
        int age = userInfo.getInt("age", 0);//讀取age
        Log.i(TAG, "讀取用戶信息");
        Log.i(TAG, "username:" + username + "董习, age:" + age);
    }

    /**
     * 移除年齡信數(shù)據(jù)
     */
    private void removeUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = userInfo.edit();//獲取Editor
        editor.remove("age");
        editor.commit();
        Log.i(TAG, "移除年齡數(shù)據(jù)");
    }

    /**
     * 清空數(shù)據(jù)
     */
    private void clearUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = userInfo.edit();//獲取Editor
        editor.clear();
        editor.commit();
        Log.i(TAG, "清空數(shù)據(jù)");
    }
}

得到log:

log

參考:
google開發(fā)者文檔
http://www.cnblogs.com/linjiqin/archive/2011/05/26/2059133.html

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末烈和,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子皿淋,更是在濱河造成了極大的恐慌招刹,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窝趣,死亡現(xiàn)場離奇詭異疯暑,居然都是意外死亡,警方通過查閱死者的電腦和手機哑舒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門妇拯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洗鸵,你說我怎么就攤上這事乖阵⌒猓” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵瞪浸,是天一觀的道長儒将。 經(jīng)常有香客問我,道長对蒲,這世上最難降的妖魔是什么钩蚊? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蹈矮,結(jié)果婚禮上砰逻,老公的妹妹穿的比我還像新娘。我一直安慰自己泛鸟,他們只是感情好蝠咆,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著北滥,像睡著了一般刚操。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上再芋,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天菊霜,我揣著相機與錄音,去河邊找鬼济赎。 笑死鉴逞,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的司训。 我是一名探鬼主播构捡,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼壳猜!你這毒婦竟也來了勾徽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蓖谢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后譬涡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闪幽,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年涡匀,在試婚紗的時候發(fā)現(xiàn)自己被綠了盯腌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡陨瘩,死狀恐怖腕够,靈堂內(nèi)的尸體忽然破棺而出级乍,到底是詐尸還是另有隱情,我是刑警寧澤帚湘,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布玫荣,位于F島的核電站,受9級特大地震影響大诸,放射性物質(zhì)發(fā)生泄漏捅厂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一资柔、第九天 我趴在偏房一處隱蔽的房頂上張望焙贷。 院中可真熱鬧,春花似錦贿堰、人聲如沸辙芍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽故硅。三九已至,卻和暖如春注簿,著一層夾襖步出監(jiān)牢的瞬間契吉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工诡渴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捐晶,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓妄辩,卻偏偏與公主長得像惑灵,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子眼耀,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容