保存されている値を使用する 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"/>
ユーザーがこのスイッチを On
に切り替えると、"notifications" : "true"
という Key-Value ペアで SharedPreferences
ファイルが更新されます。使用されるキーは、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); }
カスタム データストアの使用
Preference
オブジェクトの保持には SharedPreferences
を使用することが推奨されますが、カスタム データストアも使用できます。カスタム データストアは、アプリがデータベースに値を保持する場合や、値がデバイスに固有の場合などに便利です。
データストアを実装する
カスタム データストアを実装するには、まず、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
用に設定されているデータストアは、対応する階層用に設定されているデータストアをすべてオーバーライドします。ほとんどの場合、階層全体でデータストアを設定する必要があります。