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