使用已儲存的偏好設定值 Android Jetpack 的一部分。
本文說明如何儲存及使用 Preference 程式庫儲存的 Preference
值。
Preference 資料儲存
本節說明 Preference
如何保存資料。
SharedPreferences
根據預設,Preference
會使用 SharedPreferences
儲存值。SharedPreferences
API 支援從跨應用程式工作階段儲存的檔案,讀取及寫入簡單的鍵/值組合。偏好設定程式庫使用私人 SharedPreferences
執行個體,因此只有您的應用程式可以存取。
舉例來說,假設 SwitchPreferenceCompat
如下:
<SwitchPreferenceCompat app:key="notifications" app:title="Enable message notifications"/>
使用者將此按鈕切換為「開啟」時,SharedPreferences
檔案會更新為 "notifications" : "true"
的鍵/值組合。使用的金鑰與為 Preference
設定的鍵相同。
如要進一步瞭解 SharedPreferences
API,請參閱「儲存鍵/值資料」。
如要瞭解在 Android 中儲存資料的各種方式,請參閱「資料和檔案儲存空間總覽」。
PreferenceDataStore
雖然偏好設定程式庫預設使用 SharedPreferences
保留資料,但 SharedPreferences
不一定是理想的解決方案。例如,如果應用程式要求使用者登入,建議您將應用程式設定保留在雲端,讓設定也反映在其他裝置和平台上。同樣地,如果應用程式有裝置專屬的設定選項,則裝置上的每位使用者都有各自的設定,因此 SharedPreferences
並非理想解決方案。
PreferenceDataStore
可讓您使用自訂儲存空間後端保留 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 |
---|---|
在單一 Preference 上設定。 |
套用至所有 Preference 物件。 |
在 Preference 即將變更儲存的值時呼叫,即使待處理的值與儲存的值相同也一樣。 |
只有在儲存 Preference 的值變更時才會呼叫。 |
只能透過 Preference 程式庫呼叫。應用程式的個別部分可以變更儲存的值。 |
每當儲存的值變更時都會呼叫,即使值來自應用程式個別部分也一樣。 |
在儲存待處理的值之前呼叫。 | 儲存值後會呼叫。 |
在使用 SharedPreferences 或 PreferenceDataStore 時呼叫。 |
僅在使用 SharedPreferences 時呼叫。 |
實作 OnPreferenceChangeListener
實作 OnPreferenceChangeListener
可讓您監聽 Preference
值的待處理變更。接著,您可以驗證變更是否發生。例如,以下程式碼說明如何監聽索引鍵為 "name"
的 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
儲存的值何時發生變更,例如與伺服器同步設定時。以下範例說明如何透過 "name"
索引鍵監聽 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
設定的資料儲存庫,會覆寫為對應階層設定的任何資料儲存庫。在大多數情況下,您會為整個階層設定資料儲存庫。