在開發程式時如果有需要儲存一些名稱 (key) 與值 (value) 的對應資料 (只限基本型態的資料,如:int, float, boolean, long 等),可透過 SharedPreferences 物件來達成。例如使用者在成功登入 App 之後將帳號記錄下來,在下次登入時自動帶出,此時使用者就只需要輸入密碼即可。
infor from: http://android-deve.blogspot.tw/2012/11/sharedpreferences-keyvalue.html
A. 使用的物件以及方法
- Context
- SharedPreferences getSharedPreference(String name, int mode)
- Activity
- SharedPreferences getPreferences(int mode)
- SharedPreferences
- public abstract boolean contains(String key)
- public abstract SharedPreferences.Editor edit()
- public abstract Map<String, ?> getAll()
- public abstract boolean getBoolean(String key, boolean defValue)
- public abstract float getFloat(String key, float defValue)
- public abstract int getInt(String key, int defValue)
- public abstract long getLong(String key, long defValue)
- public abstract String getString(String key, String defValue)
- public abstract Set<String> getStringSet(String key, Set<String> defValues)
- SharedPreferences.Editor
- public abstract void apply()
- public abstract Editor clear()
- public abstract boolean commit()
- public abstract Editor putBoolean(String key, boolean value)
- public abstract Editor putFloat(String key, float value)
- public abstract Editor putInt(String key, int value)
- public abstract Editor putLong(String key, long value)
- public abstract Editor putString(String key, String value)
- public abstract Editor putStringSet(String key, Set<String> values)
- public abstract Editor remove(String key)
B. 原理說明
- 在 Android 平台上一個 SharedPreferences 物件會對應到一個檔案,這個檔案中儲存 key/value 的對應資料,而SharedPreferences 物件提供了一些對應的方法來讀寫這些資料。
- 每一個儲存 key/value 的 SharedPreferences 檔案都是由 Android 平台管理,在取得 SharedPreferences 物件時系統會自動建立 SharedPreference 檔案 (如果檔案不存在就會建立一個新的),可透過參數設定該檔案的權限只有目前 App 可以存取,或開放給其他 App 讀取或寫入 (當然,其他 App 要知道這個檔案的擺放位置才行)。
- 使用 Context.getSharedPreference(String name, int mode) 方法可以建立多個 SharedPreferences 檔案,每一個檔案透過 name 參數來命名,該檔案的讀寫權限則是利用 mode 參數來做設定。
- Context.getSharedPreference() 方法執行後,系統就會在 /data/data/[package.name]/shared_prefs/ 目錄底下建立一個 name.xml 的檔案 (name 就是該方法傳入的參數),並依據 mode 參數來設定檔案的讀寫權限。舉例來說,在 com.myapp.MyActivity 中呼叫 getApplication().getSharedPreferences("ap_setting", Context.MODE_PRIVATE); 之後,就會在 /data/data/com.myapp/ 目錄下產生一個 ap_setting.xml 檔案。
- 使用 Activity.getPreferences(int mode) 可以建立一個讓目前的 Activity 使用的 SharedPreferences 檔案 (其他的 Activity 無法使用)。事實上 getPreferences(int mode) 底層也是呼叫 Context.getSharedPreference(String name, int mode) 方法,並將目前 Activity 的名稱當作 name 參數傳入。因此,這個方法執行後會在 /data/data/[package.name]/shared_prefs/ 目錄底下會產生一個以 Activity 名稱為檔名的 XML 檔,如:MyActivity.xml。
- 在呼叫 Context.getSharedPreference() 或 Activity.getPreferences() 來取得 SharedPreferences 物件時,系統會檢查對應的 SharedPreferences 檔案是否存在,如果存在就將 SharedPreferences 物件指向該檔案,若不存在則會建立一個新的檔案,並將物件指向該檔案。
- getPreferences() 方法中的 mode 參數可以是以下三種:
- MODE_PRIVATE: 建立的 SharedPreferences 檔案只能讓目前的 App 讀寫
- MODE_WORLD_READABLE: 除了目前 App 可以讀寫外,也能讓其他的 App 讀取,當然其他 App 要知道該檔案的擺放位置
- MODE_WORLD_WRITEABLE: 除了目前 App 可以讀寫外,也能讓其他的 App 寫入,當然其他 App 要知道該檔案的擺放位置
- 要修改 SharedPreferences 裡面的資料 (將資料存入或刪除) 必須透過 SharedPreferences.Editor 物件來達成,當SharedPreferences 裡面的資料被修改後,必須呼叫 commit() 或 apply() 讓修改結果生效。commit() 與 apply() 的差別在於 commit() 會直接將異動結果寫入檔案,apply() 則是修改記憶體中的暫存資料,並以非同步方式將結果寫入檔案中。
C. 使用方式
1. 取得 SharedPreferences 物件讓目前的 Activity 使用
//取得一個 SharedPreferences 物件讓目前的 Activity 使用,
//產生的 SharedPreferences 檔案「無法讓其他 App 存取」
SharedPreferences spref = getPreferences(MODE_PRIVATE);
...
//取得一個 SharedPreferences 物件讓目前的 Activity 使用,
//產生的 SharedPreferences 檔案「可以讓其他 App 讀取」
SharedPreferences spref = getPreferences(MODE_WORLD_READABLE);
...
//取得一個 SharedPreferences 物件讓目前的 Activity 使用,
//產生的 SharedPreferences 檔案「可以讓其他 App 寫入」
SharedPreferences spref = getPreferences(MODE_WORLD_WRITEABLE);
...
2. 取得 SharedPreferences 物件讓多個 Activity 使用
//KEY 值可以任意給定,只要用同一個 KEY 就可以存取同一個 SharedPreferences 檔案
public static final String KEY = "com.my.package.app";
...
//取得一個 SharedPreferences 物件讓同一個 App 裡面的不同 Activity 可以共同使用
SharedPreferences spref = getApplication().
getSharedPreference(KEY, Context.MODE_PRIVATE);
3. 將資料存入 SharedPreferences
//由 SharedPreferences 中取出 Editor 物件,透過 Editor 物件將資料存入
SharedPreferences.Editor editor = spref.edit();
//清除 SharedPreferences 檔案中所有資料
editor.clear();
//儲存 boolean 型態的資料
editor.putBoolean("KEY_BOOL", true);
//儲存 float 型態的資料
editor.putFloat("KEY_FLOAT", 18);
//將目前對 SharedPreferences 的異動寫入檔案中
//如果沒有呼叫 apply(),則異動的資料不會生效
editor.apply();
//儲存 long 型態的資料
editor.putLong("KEY_LONG", 100);
//儲存字串型態的資料
editor.putString("KEY_STRING", "Android 開發");
//儲存集合型態的資料
HashSet<String> hs = new HashSet<String>();
hs.add("一月"); hs.add("二月");
editor.putStringSet("KEY_STR_SET", hs);
//移除 KEY_STRING 對應的資料
editor.remove("KEY_STRING");
//將目前對 SharedPreferences 的異動寫入檔案中
//如果沒有呼叫 commit(),則異動的資料不會生效
editor.commit();
4. 取出 SharedPreferences 裡面的資料
//取出 SharedPreferences 物件,若 SharedPreference 檔案不存在就會建立一個新的 SharedPreferences spref = getPreferences(MODE_PRIVATE); //透過 KEY_BOOL key 取出 boolean 型態的資料,若資料不存在則回傳 true boolean booValue = spref.getBoolean("KEY_BOOL", true); //透過 KEY_FLOAT key 取出 float 型態的資料,若資料不存在則回傳 0 float floatValue = spref.getFloat("KEY_FLOAT", 0); //透過 KEY_LONG key 取出 long 型態的資料,若資料不存在則回傳 0 long longValue = spref.getLong("KEY_LONG", 0); //透過 KEY_STRING key 取出字串型態的資料,若資料不存在則回傳 null String strValue = spref.getString("KEY_STRING", null); //透過 KEY_STR_SET key 取出集合型態的資料,若資料不存在則回傳 null HashSet<String> hs = (HashSet<String>) spref.getStringSet("KEY_STR_SET", null); //回傳 KEY_STRING 是否在在 SharedPreferences 檔案中 boolean exists = spref.contains("KEY_STRING")
D. 完整實例
package com.test; import java.util.HashSet; import android.app.Activity; import android.content.SharedPreferences; import android.os.Bundle; public class MyActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SharedPreferences spref = getPreferences(MODE_PRIVATE); SharedPreferences.Editor editor = spref.edit(); editor.clear(); editor.putBoolean("KEY_BOOL", true); editor.putFloat("KEY_FLOAT", 18); editor.apply(); editor.putLong("KEY_LONG", 100); editor.putString("KEY_STRING", "Android 開發"); HashSet<String> hs = new HashSet<String>(); hs.add("一月"); hs.add("二月"); editor.putStringSet("KEY_STR_SET", hs); editor.remove("KEY_STRING"); editor.commit(); } }當 MyActivity 的 onCreate() 執行完畢後,就會在 /data/data/com.test/shared_prefs/ 目錄下產生一個 MyActivity.xml 檔案,檔案內容如下所示:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<boolean name="KEY_BOOL" value="true" />
<long name="KEY_LONG" value="100" />
<float name="KEY_FLOAT" value="18.0" />
<set name="KEY_STR_SET">
<string>一月</string>
<string>二月</string>
</set>
</map>
沒有留言:
張貼留言