保存値を使用する   Part of Android Jetpack.

このトピックでは、Preference Library によって保存される Preference 値を格納したり使用したりする方法について説明します。

Preference データ ストレージ

このセクションでは、Preference でどのようにデータを保持できるか説明します。

SharedPreference

デフォルトの場合、Preference では値を保存するために SharedPreferences が使用されます。 SharedPreferences API を使用すると、アプリケーションの複数セッション間で、単純なキーと値のペアをファイルに保存しておき、後で読み出すことができます。 Preference Library では、SharedPreferences の限定公開インスタンスが使用されるため、自分の開発したアプリケーションだけがそれにアクセスすることができます。

たとえば、次の SwitchPreferenceCompat があるとします。

<SwitchPreferenceCompat
        app:key="notifications"
        app:title="Enable message notifications"/>

ユーザーがこのスイッチを On 状態に切り替えると、SharedPreferences ファイルが "notifications" : "true" というキー値ペアで更新されます。 使用されるキーは、Preference に設定されているキーと同じであることに注意してください。

SharedPreferences API の詳細情報については、キー値データを保存する をご覧ください。

Android でデータを格納するさまざまな方法については、データとファイルの保存の概要 をご覧ください。

PreferenceDataStore

Preference library はデフォルトで 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() callback および onPause() callback で実行してください。

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, @Nullable value: String) {
        // Save the value somewhere
    }

    @Nullable
    override fun getString(key: String, @Nullable 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 についてカスタム データ ストアを有効にするには、下の例に示されているように、PreferencesetPreferenceDataStore() を呼び出します。

Kotlin

val preference = findPreference("key")
preference.preferenceDataStore = dataStore

Java

Preference preference = findPreference(“key”);
preference.setPreferenceDataStore(dataStore);

階層全体に対してカスタム データ ストアを有効にするには、PreferenceManagersetPreferenceDataStore() を呼び出します。

Kotlin

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Java

PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setPreferenceDataStore(dataStore);

特定の Preference に設定されるデータ ストアは、対応する階層に設定されるデータ ストアよりも優先されます。 ほとんどの場合、階層全体に対してデータ ストアを設定するようにしてください。