Android and Java have many different ways to achieve persistence of data, from
reading and writing to files to setting up and using whole databases through our
code. However, the neatest, simplest, and most suitable way for the examples in this book is by using the SharedPreferences class.
In this example, we will use the SharedPreferences class to save data. Actually, we
will be reading and writing to files, but the class hides all of the complexity from us
We will see a somewhat abstract example of persistence so that we are familiar with the code before we use something similar to save the high score in our memory game. The complete code for this example can be found in the code bundle at Chapter5/Persistence/java/MainActivity.java and Chapter5/Persistence/ layout/activity_main.xml:
1. Create a project with a blank activity, just as we did in Chapter 2, Getting Started with Android. Also, clean up the code by deleting the unnecessary
parts, but this isn't essential.
2. Open activity_main.xml in the editor window and click and drag one button from the palette to the design. The default ID of the button that is assigned is perfect for our uses, so no further work is required on the UI. 3. Open MainActivity.java in the editor window. Implement View.
onClickListener and autogenerate the required onClick method, just as we did in steps 6 and 7 of the Playing sound in Android example previously. 4. Type the following code just after the MainActivity declaration. This declares
our two objects that will do all the complex stuff behind the scenes: a bunch of strings that will be useful and a button:
SharedPreferences prefs;
SharedPreferences.Editor editor; String dataName = "MyData"; String stringName = "MyString"; String defaultString = ":-("; String currentString = "";//empty Button button1;
5. Add the next block of code to the onCreate method after the call to setContentView. We initialize our objects and set up our button. We will look closely at this code once the example is done:
//initialize our two SharedPreferences objects prefs = getSharedPreferences(dataName,MODE_PRIVATE); editor = prefs.edit();
//Either load our string or
//if not available our default string
currentString = prefs.getString(stringName, defaultString); //Make a button from the button in our layout
button1 =(Button) findViewById(R.id.button); //Make each it listen for clicks
button1.setOnClickListener(this); //load currentString to the button button1.setText(currentString);
6. Now the action takes place in our onClick method. Add this code, which generates a random number and adds it to the end of currentString. Then it saves the string and sets the value of the string to the button as well:
//we don't need to switch here! //There is only one button
//so only the code that actually does stuff //Get a random number between 0 and 9 Random randInt = new Random();
int ourRandom = randInt.nextInt(10);
//Add the random number to the end of currentString currentString = currentString + ourRandom;
//Save currentString to a file in case the user //suddenly quits or gets a phone call
editor.putString(stringName, currentString); editor.commit();
//update the button text
button1.setText(currentString);
Run the example on an emulator or a device. Notice that each time you press the button, a random number is appended to the text of the button. Now quit the app, or even shut down the device if you like. When you restart the app, our cool SharedPreferences class simply loads the last saved string.
Here is how the code works. There is nothing we haven't seen several times before
until step 4:
SharedPreferences prefs;
Here, we declare two types of SharedPreferences objects called prefs and editor. We will see exactly how we use them in a minute.
Next, we declare the dataName and stringName strings. We do this because to use the facilities of SharedPreferences, we need to refer to our collection of data, as well as any individual pieces of data within it, using a consistent name. By initializing dataName and stringName, we can use them as a name for our data store as well as
a specific item within that data store, respectively. The sad face in defaultString gets used any time the SharedPreferences object needs a default because either nothing has been previously saved or the loading process fails for some reason. The currentString variable will hold the value of the string we will be saving and loading as well as displaying to the user of our app. Our button is button1:
String dataName = "MyData"; String stringName = "MyString"; String defaultString = ":-("; String currentString = "";//empty Button button1;
In step 5, the real action starts with this code:
prefs = getSharedPreferences(dataName,MODE_PRIVATE); editor = prefs.edit();
currentString = prefs.getString(stringName, defaultString);
The previous code does stuff that would take a lot more code if we didn't have
the useful SharedPreferences class. The first two lines initialize the objects and the third loads the value from our data store item, whose name is contained in stringName, to our currentString variable. The first time this happens, it uses the defaultString value because nothing is stored there yet, but once there is a value stored, this single line of code that will load up our saved string.
At the end of step 5, we set up our button as we have done many times before. Moving on to step 6 in the onClick method, there is no switch block because there
is only one button. So if a click is detected, it must be our button. Here are the first
three lines from onClick:
Random randInt = new Random(); int ourRandom = randInt.nextInt(10); currentString = currentString + ourRandom;
We generate a random number and append it to the currentString variable. Next, still in onClick, we do this:
editor.putString(stringName, currentString); editor.commit();
This is like the opposite of the code that loaded our string in onCreate. The first
of the previous two lines identifies the place in the data store to write the value to
(stringName) and the value to be written there (currentString). The next line, editor.commit();, simply says, "go ahead and do it."
The following line displays currentString as text on our button so that we can see what is going on:
button1.setText(currentString);
For more on persistence, take a look at the second question of the Self-test questions section at the end of this chapter.