This topic describes how to store and use Preference values that are saved by
the Preference Library.

Preference data storage

This section describes how a Preference can persist data.

SharedPreferences

By default, a Preference uses SharedPreferences
to save values. The SharedPreferences API allows for reading and writing
simple key-value pairs from a file that is saved across application sessions.
The Preference Library uses a private SharedPreferences instance so that only
your application can access it.

When a user toggles this switch to the On state, the SharedPreferences file
is updated with a key-value pair of "notifications" : "true". Note that the
key used is the same as the key set for the Preference.

PreferenceDataStore

While the Preference library persists data with SharedPreferences by default,
SharedPreferences aren’t always an ideal solution. For example, if your
application requires a user to sign in, you might want to persist application
settings in the cloud so that the settings are reflected across other devices
and platforms. Similarly, if your application has configuration options that are
device-specific, each user on the device would have separate settings, making
SharedPreferences a less-than-ideal solution.

Reading Preference values

To retrieve the SharedPreferences object that is being used, call
PreferenceManager.getDefaultSharedPreferences().
This method works from anywhere in your application. For example, given an
EditTextPreference with a key of "signature":

<EditTextPreference
app:key="signature"
app:title="Your signature"/>

The saved value for this Preference can be retrieved globally as follows:

Called when a Preference is about to change its saved value. This
includes if the pending value is the same as the currently saved
value.

Called only when the value saved for a Preference has changed.

Only called through the Preference library. A separate part of the
application could change the saved value.

Called whenever the value saved has changed, even if it is from a
separate part of the application.

Called before the pending value is saved.

Called after the value has already been saved.

Called when using SharedPreferences or a PreferenceDataStore.

Called only when using SharedPreferences.

OnPreferenceChangeListener

Implementing an OnPreferenceChangeListener allows you to listen for when the
value of a Preference is about to change. From there, you can validate if this
change should occur. For example, the code below shows how to listen for a
change to the value of an EditTextPreference with a key of "name":

Kotlin

preference.onPreferenceChangeListener = ...

Java

preference.setOnPreferenceChangeListener(...);

OnSharedPreferenceChangeListener

When persisting Preference values using SharedPreferences, you can also use
a SharedPreferences.OnSharedPreferenceChangeListener to listen for changes.
This allows you to listen for when the values saved by your Preference are
changed, such as when syncing settings with a server. The example below shows
how to listen for when the value of an EditTextPreference with a key of "name"
changes:

Kotlin

Java

Warning: To prevent unintended garbage collection, you must store a strong
reference to the listener. When you call
registerOnSharedPreferenceChangeListener(), the SharedPreferenceManager does
not store a strong reference to the listener. To address this, you can implement
onSharedPreferenceChanged() directly in your PreferenceFragmentCompat. You
could also create an instance variable, as shown below:

Using a custom data store

While persisting Preference objects using SharedPreferences is recommended,
you can also use a custom data store. A custom data store can be useful if your
application persists values to a database or if values are device-specific, as
examples.

Implement the data store

To implement a custom data store, first create a class that extends
PreferenceDataStore.
The example below creates a data store that handles String values:

Note: Only override methods that are used by your Preference objects.
Attempting to call a method that you haven’t implemented results in an
UnsupportedOperationException.

Be sure to run any time-consuming operations off the main thread to avoid
blocking the user interface. Since it is possible for the Fragment or
Activity containing the data store to be destroyed while persisting a value,
you should serialize the data so you don’t lose any values changed by the user.

Enable the data store

After you have implemented your data store, you must set the new data store in
onCreatePreferences() so that Preference objects persist values with the
data store instead of using the default SharedPreferences. A data store can be
enabled for each Preference or for the entire hierarchy.

To enable a custom data store for a specific Preference, call
setPreferenceDataStore()
on the Preference, as shown in the example below: