使用已儲存的值 Android Jetpack 的一部分。
本主題說明如何儲存及使用保存於偏好設定資料庫的 Preference
值。
Preference 資料儲存
本節說明 Preference
如何保存資料。
SharedPreferences
根據預設,Preference
會使用 SharedPreferences
來儲存值。SharedPreferences
API 可讓您在不同的應用程式工作階段中,從儲存的檔案讀取及寫入簡單的鍵/值組合。偏好設定資料庫使用私人 SharedPreferences
執行個體,因此只有您的應用程式才能存取。
舉例來說,假設 SwitchPreferenceCompat
如下:
<SwitchPreferenceCompat app:key="notifications" app:title="Enable message notifications"/>
使用者將此設定切換為 On
狀態時,SharedPreferences
檔案即會更新為 "notifications" : "true"
的鍵/值組合。請注意,使用的鍵即是為 Preference
設定的鍵。
如要進一步瞭解 SharedPreferences
API,請參閱「儲存鍵/值資料」。
如要瞭解在 Android 上儲存資料的各種方式,請參閱「資料和檔案儲存空間總覽」。
PreferenceDataStore
雖然偏好設定資料庫根據預設使用 SharedPreferences
保留資料,但 SharedPreferences
不一定是理想的解決方案。例如,如果應用程式要求使用者登入,則建議您將應用程式設定保留在雲端,使設定在其他裝置和平台也保持一致。同樣地,如果應用程式有裝置專屬的設定選項,則裝置上的每位使用者都會有不同設定,因此 SharedPreferences
並不理想。
PreferenceDataStore
可讓您使用自訂儲存空間後端來保留 Preference
值。詳情請參閱使用自訂資料儲存區。
讀取 Preference 值
如要擷取目前使用的 SharedPreferences
物件,請呼叫 PreferenceManager.getDefaultSharedPreferences()
。在應用程式的任何位置皆可使用這種方法。例如,假設 EditTextPreference
含有 "signature" 索引鍵:
<EditTextPreference app:key="signature" app:title="Your signature"/>
此 Preference
已儲存的值可在全域擷取,如下所示:
Kotlin
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */) val name = sharedPreferences.getString("signature", "")
Java
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */); String name = sharedPreferences.getString(“signature”, "");
監聽 Preference 值的變更
如要監聽 Preference
值的變更,您可以選擇在兩個介面之間切換:
下表列出了這兩個介面的差異:
OnPreferenceChangeListener | OnSharedPreferenceChangeListener |
---|---|
每個偏好設定分別設定 | 套用至所有偏好設定 |
在偏好設定即將變更儲存的值時呼叫,這包括待處理的值是否與目前儲存的值相同。 | 只有在偏好設定的儲存值變更時才會呼叫。 |
只能透過偏好設定資料庫呼叫。應用程式的個別部分可能會變更儲存的值。 | 每當儲存的值發生變更時都會呼叫,即使值來自應用程式個別部分也是如此。 |
在儲存待處理的值之前呼叫。 | 在儲存值之後呼叫。 |
在使用 SharedPreferences 或 PreferenceDataStore 時呼叫。 |
僅在使用 SharedPreferences 時呼叫。 |
OnPreferenceChangeListener
您可以透過實作 OnPreferenceChangeListener
監聽 Preference
的值何時將要變更,然後驗證是否應發生此變更。例如,以下程式碼示範如何監聽含有「名稱」索引鍵的 EditTextPreference
值變更:
Kotlin
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean { Log.e("preference", "Pending Preference value is: $newValue") return true }
Java
@Override public boolean onPreferenceChange(Preference preference, Object newValue) { Log.e("preference", "Pending Preference value is: " + newValue); return true; }
接著,您需要直接使用 setOnPreferenceChangeListener()
設定此事件監聽器,如下所示:
Kotlin
preference.onPreferenceChangeListener = ...
Java
preference.setOnPreferenceChangeListener(...);
OnSharedPreferenceChangeListener
使用 SharedPreferences
保留 Preference
值時,您還可以使用 SharedPreferences.OnSharedPreferenceChangeListener
來監聽變更。這樣一來,您就可以監聽 Preference
儲存的值何時變更,例如在與伺服器同步設定時變更。以下範例說明如何監聽含有「名稱」索引鍵的 EditTextPreference
值何時變更:
Kotlin
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { if (key == "signature") { Log.i(TAG, "Preference value was updated to: " + sharedPreferences.getString(key, "")) } }
Java
@Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (key.equals(“signature”)) { Log.i(TAG, “Preference value was updated to: “ + sharedPreferences.getString(key, "")); } }
您還必須透過 registerOnSharedPreferenceChangedListener()
註冊事件監聽器,如下所示:
Kotlin
preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)
Java
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(...);
Kotlin
val listener: SharedPreferences.OnSharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener {...}
Java
SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {...}
為妥善管理 Activity
或 Fragment
中的生命週期,您必須在 onResume()
和 onPause()
回呼中註冊及取消註冊此事件監聽器,如下所示:
Kotlin
override fun onResume() { super.onResume() preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this) } override fun onPause() { super.onPause() preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) }
Java
@Override public void onResume() { super.onResume(); getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); } @Override public void onPause() { super.onPause(); getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); }
使用自訂資料儲存區
建議使用 SharedPreferences
保留 Preference
物件,但也可以使用自訂資料儲存區。如果您的應用程式會將資料保留在資料庫,或者值因裝置而異,自訂資料儲存區就很實用,如範例所示。
實作資料儲存區
如要實作自訂資料儲存區,請先建立延伸 PreferenceDataStore
的類別。以下範例會建立可處理 String
值的資料儲存區:
Kotlin
class DataStore : PreferenceDataStore() { override fun putString(key: String, value: String?) { // Save the value somewhere } override fun getString(key: String, defValue: String?): String? { // Retrieve the value } }
Java
public class DataStore extends PreferenceDataStore { @Override public void putString(String key, @Nullable String value) { // Save the value somewhere } @Override @Nullable public String getString(String key, @Nullable String defValue) { // Retrieve the value } }
請務必在主要執行緒上執行任何耗時的作業,以免影響使用者介面。由於在保留值時可能會刪除包含資料儲存區的 Fragment
或 Activity
,因此請將資料序列化,以免遺失使用者變更的任何值。
啟用資料儲存區
資料儲存區實作完畢後,必須在 onCreatePreferences()
中設定新的資料儲存區,讓 Preference
物件可在資料儲存區中保留值,而非使用預設 SharedPreferences
。您可為每個 Preference
啟用一個資料儲存區,也可為整個階層啟用。
如要為特定 Preference
啟用自訂資料儲存區,請在 Preference
呼叫 setPreferenceDataStore()
,如以下範例所示:
Kotlin
val preference: Preference? = findPreference("key") preference?.preferenceDataStore = dataStore
Java
Preference preference = findPreference(“key”); if (preference != null) { preference.setPreferenceDataStore(dataStore); }
如要為整個階層啟用自訂資料儲存區,請在 PreferenceManager
呼叫 setPreferenceDataStore()
:
Kotlin
val preferenceManager = preferenceManager preferenceManager.preferenceDataStore = dataStore
Java
PreferenceManager preferenceManager = getPreferenceManager(); preferenceManager.setPreferenceDataStore(dataStore);
為特定 Preference
設定的資料儲存區,會覆寫為相應階層設定的任何資料儲存區。大部分情況下,您都應為整個階層設定資料儲存區。