保存した設定値を使用する Android Jetpack の一部。

このドキュメントでは、Preference ライブラリによって保存される Preference 値を格納して使用する方法について説明します。

Preference のデータ保存

このセクションでは、Preference でのデータの保持方法について説明します。

SharedPreferences

デフォルトでは、PreferenceSharedPreferences を使用して値を保存します。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 でカスタム データストアを有効にするには、次の例に示すように、PreferencesetPreferenceDataStore() を呼び出します。

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 用に設定されているデータストアは、対応する階層用に設定されているデータストアをオーバーライドします。ほとんどの場合、階層全体に対してデータストアを設定します。