保存した設定値を使用する 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
値を保持できます。詳細については、カスタム データストアを使用するをご覧ください。
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 |
---|---|
単一の 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
用に設定されているデータストアは、対応する階層用に設定されているデータストアをオーバーライドします。ほとんどの場合、階層全体に対してデータストアを設定します。