1. Welcome
Introduction
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.
The data you save to shared preferences is different from the data in the saved activity state, which you learned about in an earlier chapter:
- Data in a saved activity instance state is retained across activity instances in the same user session.
- Shared preferences persist across user sessions. Shared preferences persist even if your app stops and restarts, or if the device reboots.
Use shared preferences only when you need to save a small amount of data as simple key/value pairs. To manage larger amounts of persistent app data, use a storage method such as the Room library or an SQL database.
What you should already know
You should be familiar with:
- Creating, building, and running apps in Android Studio.
- Designing layouts with buttons and text views.
- Using styles and themes.
- Saving and restoring activity instance state.
What you'll learn
- How to identify what shared preferences are.
- How to create a shared preferences file for your app.
- How to save data to shared preferences, and read those preferences back again.
- How to clear the data in the shared preferences.
What you'll do
- Update an app so it can save, retrieve, and reset shared preferences.
2. App overview
The HelloSharedPrefs app is another variation of the HelloToast app you created in Lesson 1. It includes buttons to increment the number, to change the background color, and to reset both the number and color to their defaults. The app also uses themes and styles to define the buttons.
You start with the starter app and add shared preferences to the main activity code. You also add a reset button that sets both the count and the background color to the default, and clears the preferences file.
3. Task 1: Explore HelloSharedPrefs
The complete starter app project for this practical is available at HelloSharedPrefs-Starter. In this task you load the project into Android Studio and explore some of the app's key features.
1.1 Open and run the HelloSharedPrefs project
- Download the HelloSharedPrefs-Starter code.
- Open the project in Android Studio, and build and run the app.
Test the app by trying these steps:
- Click the Count button to increment the number in the main text view.
- Click any of the color buttons to change the background color of the main text view.
- Rotate the device and note that both background color and count are preserved.
- Click the Reset button to set the color and count back to the defaults.
Now test what happens when you quit and restart the app:
- Force-quit the app using one of these methods:
- In Android Studio, select Run > Stop ‘app' or click the Stop Icon
in the toolbar.
- On the device, press the Recents button (the square button in the lower right corner). Swipe the HelloSharedPrefs app card to quit the app, or click the X in the right corner of the card. If you quit the app in this manner, wait a few seconds before starting it again so the system can clean up.
- Re-run the app. The app restarts with the default appearance—the count is 0, and the background color is grey.
1.2 Explore the Activity code
- Open
MainActivity
. - Examine the code.
Note these things:
- The count (
mCount
) is defined as an integer. ThecountUp()
onClick method increments this value and updates the mainTextView
. - The color (
mColor
) is also an integer that is initially defined as grey in thecolors.xml
resource file asdefault_background
. - The
changeBackground()
onClick method gets the background color of the button that was clicked, and then sets the main text view to that color. - Both the
mCount
andmColor
integers are saved to the instance state bundle inonSaveInstanceState()
, and restored inonCreate()
. The bundle keys for count and color are defined by private variables (COUNT_KEY
) and (COLOR_KEY
).
4. Task 2: Save and restore data to a shared preferences file
In this task you save the state of the app to a shared preferences file, and read that data back in when the app is restarted. Because the state data that you save to the shared preferences (the current count and color) are the same data that you preserve in the instance state, you don't have to do it twice. You can replace the instance state altogether with the shared preference state.
2.1 Initialize the preferences
- Add member variables to the
MainActivity
class to hold the name of the shared preferences file, and a reference to aSharedPreferences
object.
private SharedPreferences mPreferences;
private String sharedPrefFile =
"com.example.android.hellosharedprefs";
You can name your shared preferences file anything you want to, but conventionally it has the same name as the package name of your app.
- In the
onCreate()
method, initialize the shared preferences. Insert this code before theif
statement:
mPreferences = getSharedPreferences(sharedPrefFile, MODE_PRIVATE);
The getSharedPreferences()
method (from the activity Context
) opens the file at the given filename (sharedPrefFile
) with the mode MODE_PRIVATE
.
Solution code for MainActivity
, partial:
public class MainActivity extends AppCompatActivity {
private int mCount = 0;
private TextView mShowCount;
private int mColor;
private SharedPreferences mPreferences;
private String sharedPrefFile =
"com.example.android.hellosharedprefs";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mShowCount = (TextView) findViewById(R.id.textview);
mColor = ContextCompat.getColor(this,
R.color.default_background);
mPreferences = getSharedPreferences(
sharedPrefFile, MODE_PRIVATE);
// ...
}
}
2.2 Save preferences in onPause()
Saving preferences is a lot like saving the instance state – both operations set aside the data to a Bundle object as a key/value pair. For shared preferences, however, you save that data in the onPause()
lifecycle callback, and you need a shared editor object ( SharedPreferences.Editor
) to write to the shared preferences object.
- Add the
onPause()
lifecycle method toMainActivity
.
@Override
protected void onPause() {
super.onPause();
// ...
}
- In
onPause()
, get an editor for theSharedPreferences
object:
SharedPreferences.Editor preferencesEditor = mPreferences.edit();
A shared preferences editor is required to write to the shared preferences object. Add this line to onPause()
after the call to super.onPause()
.
- Use the
putInt()
method to put both themCount
andmColor
integers into the shared preferences with the appropriate keys:
preferencesEditor.putInt(COUNT_KEY, mCount);
preferencesEditor.putInt(COLOR_KEY, mColor);
The SharedPreferences.Editor
class includes multiple "put" methods for different data types, including putInt()
and putString()
.
- Call
apply()
to save the preferences:
preferencesEditor.apply();
The apply()
method saves the preferences asynchronously, off of the UI thread. The shared preferences editor also has a commit()
method to synchronously save the preferences. The commit()
method is discouraged as it can block other operations.
- Delete the entire
onSaveInstanceState()
method. Because the activity instance state contains the same data as the shared preferences, you can replace the instance state altogether.
Solution code for MainActivity
onPause()
method:
@Override
protected void onPause() {
super.onPause();
SharedPreferences.Editor preferencesEditor = mPreferences.edit();
preferencesEditor.putInt(COUNT_KEY, mCount);
preferencesEditor.putInt(COLOR_KEY, mColor);
preferencesEditor.apply();
}
2.3 Restore preferences in onCreate()
As with the instance state, your app reads any saved shared preferences in the onCreate()
method. Again, because the shared preferences contain the same data as the instance state, we can replace the state with the preferences here as well. Every time onCreate()
is called – when the app starts, on configuration changes – the shared preferences are used to restore the state of the view.
- Locate the part of the
onCreate()
method that tests if thesavedInstanceState
argument is null and restores the instance state:
if (savedInstanceState != null) {
mCount = savedInstanceState.getInt(COUNT_KEY);
if (mCount != 0) {
mShowCountTextView.setText(String.format("%s", mCount));
}
mColor = savedInstanceState.getInt(COLOR_KEY);
mShowCountTextView.setBackgroundColor(mColor);
}
- Delete that entire block.
- In the
onCreate()
method, in the same spot where the instance state code was, get the count from the preferences with theCOUNT_KEY
key and assign it to themCount
variable.
mCount = mPreferences.getInt(COUNT_KEY, 0);
When you read data from the preferences you don't need to get a shared preferences editor. Use any of the "get" methods on a shared preferences object (such as getInt()
or getString()
to retrieve preference data.
Note that the getInt()
method takes two arguments: one for the key, and the other for the default value if the key cannot be found. In this case the default value is 0, which is the same as the initial value of mCount
.
- Update the value of the main
TextView
with the new count.
mShowCountTextView.setText(String.format("%s", mCount));
- Get the color from the preferences with the
COLOR_KEY
key and assign it to themColor
variable.
mColor = mPreferences.getInt(COLOR_KEY, mColor);
As before, the second argument to getInt()
is the default value to use in case the key doesn't exist in the shared preferences. In this case you can just reuse the value of mColor
, which was just initialized to the default background further up in the method.
- Update the background color of the main text view.
mShowCountTextView.setBackgroundColor(mColor);
- Run the app. Click the Count button and change the background color to update the instance state and the preferences.
- Rotate the device or emulator to verify that the count and color are saved across configuration changes.
- Force-quit the app using one of these methods:
- In Android Studio, select Run > Stop ‘app.'
- On the device, press the Recents button (the square button in the lower right corner). Swipe the HelloSharedPrefs app card to quit the app, or click the X in the right corner of the card.
- Re-run the app. The app restarts and loads the preferences, maintaining the state.
Solution code for MainActivity
onCreate()
method:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize views, color, preferences
mShowCountTextView = (TextView) findViewById(R.id.count_textview);
mColor = ContextCompat.getColor(this, R.color.default_background);
mPreferences = getSharedPreferences(
mSharedPrefFile, MODE_PRIVATE);
// Restore preferences
mCount = mPreferences.getInt(COUNT_KEY, 0);
mShowCountTextView.setText(String.format("%s", mCount));
mColor = mPreferences.getInt(COLOR_KEY, mColor);
mShowCountTextView.setBackgroundColor(mColor);
}
2.4 Reset preferences in the reset() click handler
The reset button in the starter app resets both the count and color for the activity to their default values. Because the preferences hold the state of the activity, it's important to also clear the preferences at the same time.
- In the
reset()
onClick method, after the color and count are reset, get an editor for theSharedPreferences
object:
SharedPreferences.Editor preferencesEditor = mPreferences.edit();
- Delete all the shared preferences:
preferencesEditor.clear();
- Apply the changes:
preferencesEditor.apply();
Solution code for the reset()
method:
public void reset(View view) {
// Reset count
mCount = 0;
mShowCountTextView.setText(String.format("%s", mCount));
// Reset color
mColor = ContextCompat.getColor(this, R.color.default_background);
mShowCountTextView.setBackgroundColor(mColor);
// Clear preferences
SharedPreferences.Editor preferencesEditor = mPreferences.edit();
preferencesEditor.clear();
preferencesEditor.apply();
}
5. Solution code
Android Studio project: HelloSharedPrefs
6. Coding challenge
Challenge: Modify the HelloSharedPrefs app so that instead of automatically saving the state to the preferences file, add a second activity to change, reset, and save those preferences. Add a button to the app named Settings to launch that activity. Include toggle buttons and spinners to modify the preferences, and Save and Reset buttons for saving and clearing the preferences.
7. Summary
- The
SharedPreferences
class allows an app to store small amounts of primitive data as key-value pairs. - Shared preferences persist across different user sessions of the same app.
- To write to the shared preferences, get a
SharedPreferences.Editor
object. - Use the various "put" methods in a
SharedPreferences.Editor
object, such asputInt()
orputString()
, to put data into the shared preferences with a key and a value. - Use the various "get" methods in a
SharedPreferences
object, such asgetInt()
orgetString()
, to get data out of the shared preferences with a key. - Use the
clear()
method in aSharedPreferences.Editor
object to remove all the data stored in the preferences. - Use the
apply()
method in aSharedPreferences.Editor
object to save the changes to the preferences file.
8. Related concept
The related concept documentation is in 9.0: Data storage and 9.1: Shared preferences.
9. Learn more
Android developer documentation:
Stack Overflow:
10. Homework
This section lists possible homework assignments for students who are working through this codelab as part of a course led by an instructor. It's up to the instructor to do the following:
- Assign homework if required.
- Communicate to students how to submit homework assignments.
- Grade the homework assignments.
Instructors can use these suggestions as little or as much as they want, and should feel free to assign any other homework they feel is appropriate.
If you're working through this codelab on your own, feel free to use these homework assignments to test your knowledge.
Build and run an app
Open the ScoreKeeper app that you created in the Android fundamentals 5.1: Drawables, styles, and themes lesson.
- Replace the saved instance state with shared preferences for each of the scores.
- To test the app, rotate the device to ensure that configuration changes read the saved preferences and update the UI.
- Stop the app and restart it to ensure that the preferences are saved.
- Add a Reset button that resets the score values to 0 and clears the shared preferences.
Answer these questions
Question 1
In which lifecycle method do you save the app state to shared preferences?
Question 2
In which lifecycle method do you restore the app state?
Question 3
Can you think of a case where it makes sense to have both shared preferences and instance state?
Submit your app for grading
Guidance for graders
Check that the app has the following features:
- The app retains the scores when the device is rotated.
- The app retains the current scores after the app is stopped and restarted.
- The app saves the current scores to the shared preferences in the
onPause()
method. - The app restores shared preferences in the
onCreate()
method. - The app displays a Reset button that resets the scores to 0.
Make sure that the implementation of the on-click handler method for the Reset button does the following things:
- Resets both score variables to 0.
- Updates both text views.
- Clears the shared preferences.
11. Next codelab
To find the next practical codelab in the Android Developer Fundamentals (V2) course, see Codelabs for Android Developer Fundamentals (V2).
For an overview of the course, including links to the concept chapters, apps, and slides, see Android Developer Fundamentals (Version 2).