By default, the Preference class stores its
values into the SharedPreferences interface, which
is the recommended way to persist user preferences. However, providing a
custom data store to your preferences can be useful if your app stores the
preferences in a cloud or local database, or if the preferences are
device-specific.
Android O lets you achieve this by providing any
Preference with your implementation of
PreferenceDataStore.
Implementing the data store
To provide your custom data store, you need to implement the
PreferenceDataStore interface.
Note: Override only those methods that are used by your
Preferences.
Refer to the following sample code:
public class MyDataStore implements PreferenceDataStore {
@Override
public void putString(String key, @Nullable String value) {
// Write the value somewhere ...
}
@Override
@Nullable
public void getString(String key, @Nullable String defValue) {
// Read the value from somewhere and return ...
}
}
When you implement the data store, run any time-expensive operations in the background to prevent blocking the user interface. After the data store receives a value to store, persist the value. This means you need to plan on how to serialize the data in case the activity holding the data store gets killed.
Providing a data store to preferences
After you have your data store, assign it to a
Preference instance. This means that methods like
getPersistedString()
and persistString() on
the Preference use the given data store instead
of the SharedPreferences. You can assign your data
store either directly to a Preference instance or
to a PreferenceManager instance. Refer to the
following sample code that demonstrates both the cases:
public static class SettingsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
// Assign the data store to a single preference
findPreference("myPref").setPreferenceDataStore(new MyDataStore());
// Assign the data store to all the preferences in the current fragment
getPreferenceManager().setPreferenceDataStore(new MyDataStore());
}
...
}
When you assign a data store to a
PreferenceManager instance, all
Preferences under that manager use
that data store. To override this configuration, assign the data store
directly to a Preference. If you assign the data
store to a Preference, that preference object
uses the data store, even if you move it to somewhere else in the
preferences hierarchy. On the other hand, if you make the changes to the
PreferenceManager, the change applies to any
Preferences under that manager. If you
move Preferences to somewhere else in
the hierarchy, the setting no longer applies to it.
Note: If you assign a data store to a
Preference after the
Preference was assigned to its hierarchy, the
initial value from the data store is not propagated again.