9.1: Shared preferences
Contents:
- Shared preferences vs. saved instance state
- Creating a shared preferences file
- Saving shared preferences
- Restoring shared preferences
- Clearing shared preferences
- Listening for preference changes
- Related practical
- Learn more
Shared preferences allow you to store small amounts of primitive data as key/value pairs in a file on the device. To get a handle to a preference file, and to read, write, and manage preference data, use the SharedPreferences
class. The Android framework manages the shared preferences file itself. The file is accessible to all the components of your app, but it is not accessible to other apps.
For managing large amounts of data, use an SQLite database or other suitable storage option, which is discussed in a later chapter.
Shared preferences vs. saved instance state
In a previous chapter you learned about preserving state using saved instance states. Here is a comparison between the two:
Shared preferences | Saved instance state |
Persists across user sessions, even if your app is stopped and restarted, or if the device is rebooted. | Preserves state data across activity instances in the same user session. |
Used for data that should be remembered across user sessions, such as a user's preferred settings or their game score. | Used for data that should not be remembered across sessions, such as the currently selected tab, or any current state of an activity. |
Represented by a small number of key/value pairs. | Represented by a small number of key/value pairs. |
Data is private to the app. | Data is private to the app. |
Common use is to store user preferences. | Common use is to recreate state after the device has been rotated. |
SharedPreference
APIs are different from the Preference
APIs. The Preference
APIs can be used to build a user interface for a settings page, and they use shared preferences for their underlying implementation. For more information on settings and the Preference
APIs, see Settings.
Creating a shared preferences file
You need only one shared preferences file for your app, and it is customarily named with the package name of your app. This makes its name unique and easily associated with your app.
You create the shared preferences file in the onCreate()
method of your main activity and store it in a member variable.
private String sharedPrefFile =
"com.example.android.hellosharedprefs";
mPreferences = getSharedPreferences(sharedPrefFile, MODE_PRIVATE);
The mode argument is required, because older versions of Android had other modes that allowed you to create a world-readable or world-writable shared preferences file. These modes were deprecated in API 17, and are now strongly discouraged for security reasons. If you need to share data with other apps, use a service or a content provider.
Saving shared preferences
You save preferences in the onPause()
state of the activity lifecycle using the SharedPreferences.Editor
interface.
- Get a
SharedPreferences.Editor
. The editor takes care of all the file operations for you. When two editors are modifying preferences at the same time, the last one to callapply()
wins. - Add key/value pairs to the editor using the "put" method appropriate for the data type, for example,
putInt()
orputString()
. These methods will overwrite previously existing values of an existing key. Call
apply()
to write out your changes. Theapply()
method saves the preferences asynchronously, off of the UI thread. The shared preferences editor also has acommit()
method to synchronously save the preferences. Thecommit()
method is discouraged as it can block other operations. AsSharedPreferences
instances are singletons within a process, it's safe to replace any instance ofcommit()
withapply()
if you were already ignoring the return value.You don't need to worry about Android component lifecycles and their interaction with
apply()
writing to disk. The framework makes sure in-flight disk writes fromapply()
complete before switching states.@Override protected void onPause() { super.onPause(); SharedPreferences.Editor preferencesEditor = mPreferences.edit(); preferencesEditor.putInt("count", mCount); preferencesEditor.putInt("color", mCurrentColor); preferencesEditor.apply(); }
Restoring shared preferences
You restore shared preferences in the onCreate()
method of your activity. The "get" methods such as getInt()
or getString()
take two arguments—one for the key and one for the default value if the key cannot be found. Using the default argument, you don't have to test whether the preference exists in the file.
mPreferences = getSharedPreferences(sharedPrefFile, MODE_PRIVATE);
if (savedInstanceState != null) {
mCount = mPreferences.getInt("count", 1);
mShowCount.setText(String.format("%s", mCount));
mCurrentColor = mPreferences.getInt("color", mCurrentColor);
mShowCount.setBackgroundColor(mCurrentColor);
} else { ... }
Clearing shared preferences
To clear all the values in the shared preferences file, call the clear()
method on the shared preferences editor and apply the changes.
SharedPreferences.Editor preferencesEditor = mPreferences.edit();
preferencesEditor.putInt("number", 42);
preferencesEditor.clear();
preferencesEditor.apply();
You can combine calls to put and clear. However, when applying the preferences, the clear is always done first, regardless of whether you called clear before or after the put methods on this editor.
Listening for preference changes
There are several reasons you might want to be notified as soon as the user changes one of the preferences. In order to receive a callback when a change happens to any one of the preferences, implement the SharedPreference.OnSharedPreferenceChangeListener
interface and register the listener for the SharedPreferences
object by calling registerOnSharedPreferenceChangeListener()
.
The interface has only one callback method, onSharedPreferenceChanged()
, and you can implement the interface as a part of your activity.
public class SettingsActivity extends PreferenceActivity
implements OnSharedPreferenceChangeListener {
public static final String KEY_PREF_SYNC_CONN =
"pref_syncConnectionType";
// ...
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences,
String key) {
if (key.equals(KEY_PREF_SYNC_CONN)) {
Preference connectionPref = findPreference(key);
// Set summary to be the user-description for
// the selected value
connectionPref.setSummary(
sharedPreferences.getString(key, ""));
}
}
}
In this example, the method checks whether the changed setting is for a known preference key. It calls findPreference()
to get the Preference
object that was changed so it can modify the item's summary to be a description of the user's selection.
For proper lifecycle management in the activity, register and unregister your SharedPreferences.OnSharedPreferenceChangeListener
during the onResume()
and onPause()
callbacks, respectively:
@Override
protected void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
Hold a reference to the listener
When you call registerOnSharedPreferenceChangeListener()
, the preference manager does not currently store a reference to the listener. You must hold onto a reference to the listener, or it will be susceptible to garbage collection. Keep a reference to the listener as a class member variable in an object such as an activity that will exist as long as you need the listener.
SharedPreferences.OnSharedPreferenceChangeListener listener =
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(
SharedPreferences prefs, String key) {
// listener implementation
}
};
prefs.registerOnSharedPreferenceChangeListener(listener);
Related practical
The related practical is 9.1: Shared preferences.
Learn more
Android developer documentation:
Stack Overflow: