保存した設定値を使用する Android Jetpack の一部
このドキュメントでは、Preference ライブラリによって保存される Preference
値を格納して使用する方法について説明します。
Preference のデータ保存
このセクションでは、Preference
でのデータの保持方法について説明します。
SharedPreferences
デフォルトでは、Preference
は SharedPreferences
を使用して値を保存します。SharedPreferences
API は、アプリ セッションをまたいで保存されるファイルに対して、シンプルな Key-Value ペアの読み取りと書き込みをサポートします。Preference ライブラリは、アプリのみがアクセスできるように、プライベート SharedPreferences
インスタンスを使用します。
たとえば、次のような SwitchPreferenceCompat
があるとします。
<SwitchPreferenceCompat app:key="notifications" app:title="Enable message notifications"/>
ユーザーがこのスイッチを「オン」状態に切り替えると、SharedPreferences
ファイルが Key-Value ペア "notifications" : "true"
に更新されます。使用される鍵は、Preference
に設定された鍵と同じです。
SharedPreferences
API の詳細については、Key-Value データを保存するをご覧ください。
Android でデータを保存するさまざまな方法については、データ ストレージとファイル ストレージの概要をご覧ください。
PreferenceDataStore
Preference ライブラリは、デフォルトでは SharedPreferences
を使用してデータを保持しますが、SharedPreferences
は必ずしも理想的なソリューションではありません。たとえば、ユーザーがログインする必要があるアプリの場合は、アプリの設定をクラウドに残して、設定が他のデバイスやプラットフォームにも反映されるようにすることをおすすめします。同様に、アプリにデバイス固有の構成オプションがある場合、デバイス上の各ユーザーが個別の設定を行うため、SharedPreferences
は理想的なソリューションとは言えません。
PreferenceDataStore
を使用すると、カスタム ストレージ バックエンドを使用して Preference
値を保持できます。詳細については、カスタム データストアの使用をご覧ください。
設定値を読み取る
使用中の SharedPreferences
オブジェクトを取得するには、PreferenceManager.getDefaultSharedPreferences()
を呼び出します。
この方法はアプリのどこからでも機能しますが、アプリをレイヤに分割することをおすすめします。詳しくは、データレイヤーをご覧ください。
たとえば、キーが "signature"
の EditTextPreference
があるとします。
<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
値の変更をリッスンするには、次の 2 つのインターフェースのいずれかを選択します。
次の表に、2 つのインターフェースの違いを示します。
OnPreferenceChangeListener |
OnSharedPreferenceChangeListener |
---|---|
1 つの 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()
で新しいデータストアを設定し、デフォルトの SharedPreferences
を使用する代わりに、Preference
オブジェクトがデータストアで値を保持するようにします。データストアは、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
に対して設定されているデータストアは、対応する階層に設定されているデータストアをオーバーライドします。ほとんどの場合、階層全体に対してデータストアを設定します。