Most apps have some sort of user state that they’d like to keep track of. But many apps don’t store a lot of information. So if you don’t need to worry about internal/external storage, and you don’t want to put yourself through the file management process, then you’ve got a friend in SharedPreferences. SharedPreferences allows an app to store primitive data in key-value pairs.

This makes it incredibly easy for developers to store user state when it comes to user settings, or to keep track of small bits of important information without needing a storage permission. (Super cool, right?)

So, what can SharedPreferences do?

SharedPreferences offers a framework to save persistent data in key-value pairs. It works for any primitive data type (meaning booleans, ints, longs, floats, and strings). Which also means that it’s pretty simple to work with.

Step 1: Get a SharedPreferences object

First and foremost, to use SharedPreferences, you need to acquire a handle to SharedPreferences. Because the framework handles this data for you (that’s what makes it persistent!), you need a way to the framework storage.

Calling getSharedPreferences() enables you to retrieve a file by name, which means you can have multiple files. That will set you up well for App Backup in Android 6.0, since you will be able to include/exclude files from App Backup by referencing their name. For example, you definitely want to backup your user settings preferences file, but probably not the prefs file storing GCM IDs.

SharedPreferences sharedPref =

context.getSharedPreferences("TheFileName",

Context.MODE_PRIVATE);

If you hate super great features like App Backup, or if you really only need to store two values, then you might want to use getDefaultSharedPreferences() instead. This doesn’t allow for a named preferences file, but it is super easy to use. There’s also the option to call getPreferences() through the Activity, and that preferences file will be tied to only particular Activity. But this also means it won’t have a name, and you won’t be able to specify whether to include or exclude this file from App Backup.

Note: Your SharedPreferences data can _technically_ be private or shared, depending on what you specify when you retrieve the handler. However, you should only ever use MODE_PRIVATE. Creating world-readable/writeable files is strongly discouraged. We even deprecated those constants to make our point.

Step 2: Write into your SharedPreferences

Writing into SharedPreferences is simple, as you probably expect. Since the idea of this whole approach is simple storage of simple data. But it starts by acquiring an Editor. And then you can insert data by calling the appropriate put method (i.e. putString() to store a String value). Whichever put you choose, you’ll need two parameters: the String key, and the <type> value. And then, of course, call apply() to save your changes!

Note: Saving changes technically has two options: apply() and commit(). Most developers will want to use apply() since it writes the changes off of the main thread. While commit() writes to persistent storage synchronously, apply() will write to the in-memory storage immediately, and schedule an asynchronous write to persistent storage. Remember: writing a shared preference is disk I/O so use apply() to keep that off the main thread. #perfmatters

SharedPreferences.Editor editor = sharedPref.edit();

editor.putBoolean("music on", false);

editor.apply();

If you are using SharedPreferences to store critical user state, like whether they turned off the background music in your game, it’s a good idea to be proactive and update the SharedPreferences state every time the user unchecks that CheckBox.

Step 3: Read from SharedPreferences

Reading a value is straightforward. You just need to call the relevant get method (again). So, calling getString() will return the String value associated with that key.

boolean musicState = sharedPref.getBoolean("music on", true);

What’s interesting, though, is the default value parameter (it’s the second one up there). This value will be returned if the specified preference does not exist. Which means you can use this as a signal that a preference is missing or needs to be set. Or, you can use the default value to keep your app moving. You’ll always have a value to work with, so the app flow will never be interrupted.

It’s also helpful to read out any state values during onCreate() and then reset those values in your app, so that when the app launches, you are confident that the user will not be surprised that the background music has resumed playing. (Build magic moments, not surprises!)

But what about PreferenceActivity?

So, let’s consider this. PreferenceActivity is intended to enable you to create and store user preferences (such as which ringtone to use), with persistence. So, isn’t that basically better and more powerful than SharedPreferences?

Well, first of all, the PreferenceManager in that source uses SharedPreferences. So it’s all the same. But using a PreferenceActivity will allow you to easily manage and maintain a larger list of preferences. So if you’re interested, start with Ian Lake’s protip about the Preferences Support Library.

So say goodbye to those storage permissions and store your small amount of data in key-value pairs!

#BuildBetterApps

Follow the Android Development Patterns Collection for more!