對于 SharedPreferences ,想必不會陌生,通常我們會這麼用
Editor sharedata = getSharedPreferences("data", 0).edit();
sharedata.putString("item","hello getSharedPreferences");
sharedata.commit();
SharedPreferences 的百度定義如下:
SharedPreferences是Android平台上一個輕量級的存儲類,用來儲存應用的一些常用配置,比如Activity狀态,Activity暫停時,将此activity的狀态儲存到SharedPereferences中;當Activity重載,系統回調方法onSaveInstanceState時,再從SharedPreferences中将值取出。
SharedPreferences提供了java正常的Long、Int、String等類型資料的儲存接口。 [1] SharedPreferences類似過去Windows系統上的ini配置檔案,但是它分為多種權限,可以全局共享通路。
提示最終是以xml方式來儲存,整體效率來看不是特别的高,對于正常的輕量級而言比SQLite要好不少,如果真的存儲量不大可以考慮自己定義檔案格式。xml處理時Dalvik會通過自帶底層的本地XML Parser解析,比如XMLpull方式,這樣對于記憶體資源占用比較好。
原理:
内部是以 XML 結構儲存在 /data/data/包名/shared_prefs 檔案夾下,資料以鍵值對的形式儲存。
檔案内容:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<boolean name="first_login" value="false" />
</map>
送出方式:
apply:異步執行,沒有傳回值;
commit:同步執行,有傳回值。
建立模式:
MODE_PRIVATE:預設模式,該模式下建立的檔案隻能被目前應用或者與該應用具有相同SharedUserID的應用通路。
MODE_WORLD_READABLE:允許其他應用讀取這個模式建立的檔案。在Android N上使用該模式将抛出SecurityException異常。
MODE_WORLD_WRITEABLE:允許其他應用寫入這個模式建立的檔案。在Android N上使用該模式将抛出SecurityException異常。
MODE_APPEND:如果檔案已經存在了,則在檔案的尾部添加資料。
MODE_MULTI_PROCESS:SharedPreferences加載标志,當設定了該标志,則在磁盤上的檔案将會被檢查是否修改了,盡管SharedPreferences執行個體已經在該程序中被加載了。(雞肋,不要用,推薦用ContentProvider)
到此,基本的使用上已經沒什麼問題了,對于部配置設定置參數的存取上,都可以通過這些來實作。
SharedPreferences 真的就這些内容嗎?
并不是,它還有
registerOnSharedPreferenceChangeListener、unregisterOnSharedPreferenceChangeListener 設定監聽
getAll 擷取所有的鍵值對
更有提供的preference以鍵值對的方式來處理這種情況:自動儲存設定的資料,并立時生效。實作即為使用 SharedPreferences 。
常見的Preference控件有:
直接子類:DialogPreference, PreferenceGroup, RingtonePreference, TwoStatePreference
非直接子類:CheckBoxPreference, EditTextPreference, ListPreference, MultiSelectListPreference, PreferenceCategory, PreferenceScreen, SwitchPreference
注意,在API 29 開始被棄用,使用上需注意。
在看ACRA項目時有看到使用registerOnSharedPreferenceChangeListener來設定監聽,以此實作開關功能,這用法真是巧妙,因為這個解決了耦合的問題,通常情況下,我們設定一個開關如下:
public class A{
private boolean isEnable = false;
...
public void setEnable(boolean enable){
this.isEnable = enable;
}
...
}
這種方式顯而易見,容易。
使用時,隻需要拿到執行個體操作即可
A a = new A();
a.setEnable(true);
在學習開源項目ACRA時,看到如下用法
final SharedPreferences prefs = new SharedPreferencesFactory(app, config).create();
...
ErrorReporterImpl reporter = new ErrorReporterImpl(app, config, enableAcra, supportedAndroidVersion, checkReportsOnApplicationStart);
prefs.registerOnSharedPreferenceChangeListener(reporter);
...
其中,reporter對象為一個錯誤捕獲實作,實作了SharedPreferences.OnSharedPreferenceChangeListener,其代碼如下,
@Override
public void onSharedPreferenceChanged(@NonNull SharedPreferences sharedPreferences, @Nullable String key) {
if (ACRA.PREF_DISABLE_ACRA.equals(key) || ACRA.PREF_ENABLE_ACRA.equals(key)) {
setEnabled(SharedPreferencesFactory.shouldEnableACRA(sharedPreferences));
}
}
是不是忽然有個大膽的想法
如果在項目中,我的一些控制器在上層想設定某個啟用與否,可以通過此方式進行解耦控制,大大降低了子產品與子產品的聯系,進而在一些功能的更新、子產品的修改上更加友善,無需考慮關聯性修改的問題。
希望SharedPreferences的這種用法對你有用😊