SharedPreferences

SharedPreferences是Android中一個輕量級的數(shù)據(jù)存儲類,適用于保存應(yīng)用程序的配置參數(shù)。當(dāng)使用SharedPreferences保存數(shù)據(jù)鳄哭,內(nèi)部會自動生成xml文件來存放真正的數(shù)據(jù)岛心,而xml文件存放在/data/data/<package name>/shared_prefs目錄下。

獲取應(yīng)用程序中的SharedPreferences對象的兩種方法

  • getSharedPreferences() - 可以指定名稱來確定多個不同的參數(shù)配置文件 (Context)
// 指定名稱為"account"的配置文件默辨,模式為MODE_PRIVATE來獲取當(dāng)前程序的SharedPreferences對象,
// 若文件不存在時婴程,則直接創(chuàng)建廓奕;若存在,則直接使用
SharedPreferences sp = getSharedPreferences("account", MODE_PRIVATE);    
  • getPreferences() - 默認使用本地的Activity的類名來作為唯一的一個參數(shù)配置文件的名稱 (Activity)
// 默認使用本地的Activity類名作為參數(shù)配置文件的名稱
SharedPreferences sp = getPreferences(MODE_PRIVATE);       
  • Context中的文件創(chuàng)建模式mode
mode value description
MODE_PRIVATE 0x0000 默認模式档叔,創(chuàng)建的文件只能被應(yīng)用程序本身訪問桌粉,即為私有數(shù)據(jù),以覆蓋的方式寫入數(shù)據(jù)
MODE_WORLD_READABLE 0x0001 創(chuàng)建的文件可以被其他應(yīng)用程序進行讀取衙四,已過時
MODE_WORLD_WRITEABLE 0x0002 創(chuàng)建的文件可以被其他應(yīng)用程序進行寫入铃肯,已過時
MODE_APPEND 0x8000 首先檢查文件是否存在,存在就往文件末尾追加內(nèi)容传蹈,否則就創(chuàng)建新文件

寫入數(shù)據(jù)

  • 調(diào)用SharedPreferences的edit()方法來獲取一個編輯器對象SharedPreferences.Editor
  • 通過SharedPreferences.Editor的putString()/putBoolean()等方法來修改配置數(shù)據(jù)或添加新的配置數(shù)據(jù)
  • 使用SharedPreferences.Editor的異步方法apply()來提交編輯器的數(shù)據(jù)更改押逼,而commit()為同步方法

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

  • 通過SharedPreferences的getString()/getBoolean()等方法獲取數(shù)據(jù)

清除數(shù)據(jù)

  • 通過SharedPreferences.Editor的remove()方法可以移除指定的參數(shù)配置數(shù)據(jù)
  • 通過SharedPreferences.Editor的clear()方法可以清除所有的參數(shù)配置數(shù)據(jù)

SharedPreferences簡單的使用

使用SharedPreferences來保存簡單類型的數(shù)據(jù),如字符串惦界、整型挑格、布爾型等數(shù)據(jù),并借助Context的getFilesDir().getParent()方法來得到應(yīng)用程序包名目錄的路徑沾歪,然后再以此拼接得到xml的完整路徑:

private String getSharedPrefsFileString(Context context, String name) {
    String path = context.getFilesDir().getParent();// 獲取文件目錄的父目錄路徑
    return path + "/shared_prefs/" + name + ".xml"; // xml數(shù)據(jù)文件
}

另一種獲取SharedPreferences數(shù)據(jù)文件的方法是通過Context的getDir()方法來獲取文件的父目錄路徑漂彤,但是查看方法的源碼可知,getDir()方法會自動在目錄名稱加上app_前綴灾搏,即編程app_shared_prefs挫望,所以需要手動去掉:

private File getSharedPrefsFile(Context context, String name){
    String dirPath = context.getDir("shared_prefs", Context.MODE_PRIVATE).getPath();
    // getDir()中會在目錄名稱前自動加上app_變成app_shared_prefs
    dirPath = dirPath.replace("app_", "");  
    return new File(dirPath, name + ".xml");
}
  • activity_main.xml

由于布局代碼比較長,這里只貼出布局后的效果截圖:

prefs_layout.PNG
  • MainActivity.java

首先是各個控件的初始化:

private void initView() {
    mXMLTv = (TextView) findViewById(R.id.tv_xml);

    mUsernameEt = (EditText) findViewById(R.id.et_account_username);
    mPasswordEt = (EditText) findViewById(R.id.et_account_password);
    mAgeEt = (EditText) findViewById(R.id.et_account_age);
    mGenderRg = (RadioGroup) findViewById(R.id.rg_account_gender);
    mMaleGenderRb = (RadioButton) findViewById(R.id.rb_account_gender_male);
    mFemaleGenderRb = (RadioButton) findViewById(R.id.rb_account_gender_female);
    mResetBtn = (Button) findViewById(R.id.btn_reset);
    mSaveBtn = (Button) findViewById(R.id.btn_save);
    mRestoreBtn = (Button) findViewById(R.id.btn_restore);

    mGenderRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            switch (checkedId) {
                case R.id.rb_account_gender_male:
                    gender = true;
                    break;
                case R.id.rb_account_gender_female:
                    gender = false;
                    break;
            }
        }
    });

    mResetBtn.setOnClickListener(this);
    mSaveBtn.setOnClickListener(this);
    mRestoreBtn.setOnClickListener(this);
}

按鈕點擊事件的處理:

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn_reset:
            reset();            // 復(fù)位各個控件
            Toast.makeText(this, "Reset Account Okay", Toast.LENGTH_SHORT).show();
            break;
        case R.id.btn_save:
            // 獲取EditText控件上的文本并轉(zhuǎn)成字符串狂窑,同時去掉首尾兩端的空白符
            username = mUsernameEt.getText().toString().trim();
            if (TextUtils.isEmpty(username)) {      // return if null or ""
                Toast.makeText(this, "Username is empty.", Toast.LENGTH_SHORT).show();
                return;
            }

            password = mPasswordEt.getText().toString().trim();
            if (TextUtils.isEmpty(password)) {
                Toast.makeText(this, "Password is empty.", Toast.LENGTH_SHORT).show();
                return;
            }

            String ageString = mAgeEt.getText().toString().trim();
            if (TextUtils.isEmpty(ageString)) {
                Toast.makeText(this, "Age is empty.", Toast.LENGTH_SHORT).show();
                return;
            }
            age = Integer.valueOf(ageString);
            
            save();             // 讀取并判斷各個控件的數(shù)據(jù)媳板,并保存到SharedPreferences中
            Toast.makeText(this, "Save Account Okay", Toast.LENGTH_SHORT).show();
            break;
        case R.id.btn_restore:
            restore();          // 讀取保存在SharedPreferences中的數(shù)據(jù),并依次顯示在控件上
            Toast.makeText(this, "Restore Account Okay", Toast.LENGTH_SHORT).show();

            // 讀取SharedPreferences保存數(shù)據(jù)而生成的xml文件內(nèi)容并顯示在TextView上
            testSharedPreferencesXML();
            break;
    }
}

控件復(fù)位處理函數(shù):

private void reset() {
    mUsernameEt.setText("");
    mPasswordEt.setText("");
    mMaleGenderRb.setChecked(false);
    mFemaleGenderRb.setChecked(true);
    mAgeEt.setText("");
    mXMLTv.setText("");
}

將從控件獲取到的數(shù)據(jù)保存到SharedPreferences的處理函數(shù):

private boolean save() {
    sp = getSharedPreferences(PREFS_ACCOUNT, MODE_PRIVATE);
    SharedPreferences.Editor editor = sp.edit();        // 獲取Editor對象
    editor.putString(KEY_ACCOUNT_USERNAME, username);   // 保存字符串?dāng)?shù)據(jù)
    editor.putString(KEY_ACCOUNT_PASSWORD, password);
    editor.putBoolean(KEY_ACCOUNT_GENDER, gender);      // 保存布爾數(shù)據(jù)
    editor.putInt(KEY_ACCOUNT_AGE, age);                // 保存整型數(shù)據(jù)
    editor.apply();             // 異步提交方法
    return true;
}

從SharedPreferences中獲取數(shù)據(jù)并顯示到各個控件上:

private void restore() {
    sp = getSharedPreferences(PREFS_ACCOUNT, MODE_PRIVATE);
    username = sp.getString(KEY_ACCOUNT_USERNAME, "");  // 讀取字符串?dāng)?shù)據(jù)泉哈,默認為""
    password = sp.getString(KEY_ACCOUNT_PASSWORD, "");
    gender = sp.getBoolean(KEY_ACCOUNT_GENDER, false);  // 讀取布爾數(shù)據(jù)蛉幸,默認為false
    age = sp.getInt(KEY_ACCOUNT_AGE, -1);               // 讀取整型數(shù)據(jù),默認為-1

    mUsernameEt.setText(username);
    mPasswordEt.setText(password);
    mMaleGenderRb.setChecked(gender);
    mFemaleGenderRb.setChecked(!gender);
    mAgeEt.setText(age < 0 ? "" : String.valueOf(age)); // 若小于0丛晦,則復(fù)位為""
}

讀取SharedPreferences生成的xml數(shù)據(jù)文件:

private void testSharedPreferencesXML() {
    // String file = getSharedPrefsFileString(this, PREFS_ACCOUNT);
    File file = getSharedPrefsFile(this, PREFS_ACCOUNT);
    String text = file.getPath();
    text += "\n\n";

    FileInputStream fis = null;
    ByteArrayOutputStream out = null;
    try {
        fis = new FileInputStream(file);        // 構(gòu)建文件輸入流
        out = new ByteArrayOutputStream();      // 構(gòu)建字節(jié)數(shù)組輸出流
        int len;                                // 記錄每次讀取數(shù)據(jù)的大小奕纫,-1表示結(jié)束
        byte[] buffer = new byte[10 * 1024];    // 定義10kB大小的緩沖區(qū)
        while ((len = fis.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        text += out.toString();
        mXMLTv.setText(text);                   // 將xml內(nèi)容設(shè)置到TextView
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (out != null) {
                out.close();
            }
            if (fis != null) {
                fis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 效果演示
sharedpreferences_320x512.gif

源碼參考

SharedPreferences

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市采呐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌搁骑,老刑警劉巖斧吐,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件又固,死亡現(xiàn)場離奇詭異,居然都是意外死亡煤率,警方通過查閱死者的電腦和手機仰冠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝶糯,“玉大人洋只,你說我怎么就攤上這事≈绾矗” “怎么了识虚?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長妒茬。 經(jīng)常有香客問我担锤,道長,這世上最難降的妖魔是什么乍钻? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任肛循,我火速辦了婚禮,結(jié)果婚禮上银择,老公的妹妹穿的比我還像新娘多糠。我一直安慰自己,他們只是感情好浩考,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布夹孔。 她就那樣靜靜地躺著,像睡著了一般怀挠。 火紅的嫁衣襯著肌膚如雪析蝴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天绿淋,我揣著相機與錄音闷畸,去河邊找鬼。 笑死吞滞,一個胖子當(dāng)著我的面吹牛佑菩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播裁赠,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼殿漠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了佩捞?” 一聲冷哼從身側(cè)響起绞幌,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎一忱,沒想到半個月后莲蜘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谭确,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年票渠,在試婚紗的時候發(fā)現(xiàn)自己被綠了逐哈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡问顷,死狀恐怖昂秃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杜窄,我是刑警寧澤肠骆,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站羞芍,受9級特大地震影響哗戈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荷科,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一唯咬、第九天 我趴在偏房一處隱蔽的房頂上張望应狱。 院中可真熱鬧染乌,春花似錦、人聲如沸垮斯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蝎毡,卻和暖如春厚柳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沐兵。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工别垮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扎谎。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓碳想,卻偏偏與公主長得像,于是被迫代替她去往敵國和親毁靶。 傳聞我的和親對象是個殘疾皇子胧奔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

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