Android SDK Getting Started Guide||Chapter 10 Application Data

Chapter 10 Application Data

We are already familiar with the structure and basic elements of an Android application, including resources, manifests, and user interfaces. After embarking on the development of functional applications on the Android platform, everyone will definitely need to save data of one kind or another. The Android platform provides a variety of options for taking care of data storage tasks in applications, and this is what today's article will discuss.

Broadly speaking, there are five main types of data storage options in Android apps: saving data in the app's shared preferences, saving data in internal storage (private to the app itself), and saving data in external storage (exposed to the device) , stored in a database, and stored in a web resource accessible through the device's Internet connection. Due to space limitations, we cannot discuss these options in detail, but we will summarize the basic characteristics of each solution to help you clarify the solution to storage problems when you need to use persistent data.

1. Shared preferences

first step

Shared preferences allow everyone to save basic data types in the form of key-value pairs. An application's shared preference file is often considered the simplest data storage option, but by its nature it imposes some restrictions on what can be stored. You can use it to store basic types of numbers (such as integers, long numbers, and floating point numbers), Boolean values, and text strings. We need to assign a name to each value we save so that we can retrieve it when the application is running. Since you are likely to use shared preferences in the first app you create, we focus on them and describe them in more detail than the other options to help you solidify the necessary Knowledge.

You can try this code in your main Activity class and test it later when you run the application examples in this tutorial series. Ideally, shared preferences should be consistent with user configuration options in the application, just like selecting appearance settings. You may still remember that we once created a simple button that would display the "Ouch" text on the screen after the user clicked it. Now let's assume that we want the word "Ouch" to appear continuously on the button after the user clicks it once, and that this state remains unchanged while the application is running. This means that the initial text on the button only exists until the user clicks the action for the first time.

Let's add shared preferences to our application. At the beginning of the class, before the onCreate method, we choose a name for the shared preference:

public static final String MY_APP_PREFS = "MyAppPrefs"

Using the "public static" modifier, we can access this variable in any class within the application, so we just need to save the preference name string here. We use uppercase because the variable is a constant, which is why the "final" modifier exists. Everyone must use the same name every time they retrieve or set a data entry in the application preferences.

second step

Now let's write the shared preference content. In our onClick method, below the button's "Ouch" text setting section, try to retrieve this shared preference by name:

SharedPreferences thePrefs = getSharedPreferences(MY_APP_PREFS, 0);

You need to add an import for the "android.conent.SharedPreferences" class. Hover over the "SharedPreferences" text and use the Eclipse prompt to complete the import. The first parameter is the name of the preference we defined, and the second parameter is the base mode we use as the default option.

Now we need to specify an editor for the shared preferences to set the values:

SharedPreferences.Editor prefsEd = thePrefs.edit();

Now we can write values ​​to the shared preferences:

prefsEd.putBoolean("btnPressed", true);

Here we use a Boolean type because there are only two current states - the user has pressed the button or not yet. The editor provides several different types that we can choose from to save this set of shared preferences, each of which has its own name and value parameters. Finally, we need to commit the edit results:

prefsEd.commit();

third step

Now let's use the saved value to detect what the button should display when the user runs the application. Add shared preferences after the existing code in onCreate:

SharedPreferences thePrefs = getSharedPreferences(MY_APP_PREFS, 0);

This time we don't have to use an editor because we just need to get a value:

boolean pressed = thePrefs.getBoolean("btnPressed", false);

Now we retrieve the value using the name we have set and read the result in the variable. If the value has not been set, the second parameter is returned, which is the default value - representing a negative meaning. Now let's use that value:

if(pressed) theButton.setText("Ouch");

If the user presses the button after the application is running, the button displays the word "Ouch" directly. In subsequent articles in this series, you will see how we perform this operation while the application is running. This simple example illustrates the use of shared preferences very well. You'll find that shared preferences play an important role in helping your application cater to your users' preferences through the look and feel of your application.

2. Private internal files

first step

You can save files on the user's device's internal as well as external storage. If you save a file to internal storage, the Android system treats it as private data specific to the current application. Such files are basically part of the application and we cannot directly access them outside the application. Furthermore, if the application is removed, these files will also be cleared.

You can create a file in memory storage with the following output routine:

FileOutputStream fileOut = openFileOutput("my_file", Context.MODE_PRIVATE);

You need to import and add the "java.io.FileOutputStream" class. We provide the file name and mode. Selecting private mode means that the file will only be used by this application. If you add this part of the code to the Activity now, such as the onClick method, Eclipse will pop up an error message. This is because when we perform input/output operations, the application may encounter some errors that need to be dealt with. If our input/output operations cannot resolve such errors, Eclipse will prompt an exception and the application will stop running. In order to ensure that the application can still run normally in this situation, we need to encapsulate our input/output code in a try code block:

try{
    FileOutputStream fileOut = openFileOutput("my_file", Context.MODE_PRIVATE);
}
catch(IOException ioe){ 
    Log.e("APP_TAG", "IO Exception", ioe);
}

If the input/output operation results in an exception, the above code in the catch block will be executed, thereby writing the error message to the log. You will often use the Log class in the application in the future (import 'android.util.Log'), which will record the specific conditions that occur when the code is executed. We can define a class variable for the string label, which is the first parameter in the above code. In this way, once an error occurs, everyone can view the exception information in Android LogCat.

second step

Now back to the try block, after creating the file output routine, you can try writing the following code to the file:

String fileContent = "my data file content"
fileOut.write(fileContent.getBytes());

After writing all necessary content to the data file, conclude with the following code:

fileOut.close();

third step

When you need to retrieve the content in internal files, you can do so through the following process:

try{
    FileInputStream fileIn = openFileInput("my_file");
    //read the file
}
catch(IOException ioe){ 
    Log.e("APP_TAG", "IO Exception", ioe);
}

In the try block, use the buffered reader to read the file content:

InputStreamReader streamIn = new InputStreamReader(fileIn);
BufferedReader fileRead = new BufferedReader(streamIn);
StringBuilder fileBuild = new StringBuilder("");
String fileLine=fileRead.readLine();
while(fileLine!=null){
    fileBuild.append(fileLine+"\n");
    fileLine=fileRead.readLine();
}
String fileText = fileBuild.toString();
streamIn.close();

Don't be intimidated by the large number of different objects involved, this is actually a standard Java input/output operation. The while loop will be executed once for each line in the file. After the execution is completed, the "fileText" variable will save the file content as a string for our direct use.

3. Public external files

first step

Our application can also save files to external storage as long as the user's device supports it. There are many types of external storage, including SD cards, other portable media, or memory storage mechanisms that cannot be removed by the user but are recognized by the system as external types. When we save a file on external storage, its content is completely public and you cannot prevent users or other applications from accessing it in any way.

Before we try to save data to external storage, we must first check whether the corresponding storage mechanism is available - it is definitely a good practice to try to avoid unexpected situations:

String extStorageState = Environment.getExternalStorageState();

The system will return the information in the form of a string, which you can analyze and compare with the external storage status field in the Environment class:

if(Environment.MEDIA_MOUNTED.equals(extStorageState)){
    //ok to go ahead and read/ write to external storage
}
else if(Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)){
    //can only read
}
else{
    //cannot read or write
}

Even if external storage does exist on the device, we cannot presumptively assume that apps can write data to it.

second step

After verifying that we can indeed write data to external storage, we next need to search the directory to specify where the files are saved. The following application settings point to API level 8 and higher:

File myFile = new File(getExternalFilesDir(null), "MyFile.txt");

This allows everyone to write and read the file. But don't forget to add the following restrictions to your project's manifest file:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

As the applications we develop become more complex, you may want to share your saved files with other applications. In this case, you can use the common entries in the public directory, such as pictures and music files.

4. Database

As our applications involve more and more complex structured data, shared preferences or internal/external files may no longer be able to meet actual needs. At this time, everyone should consider using a database solution. Android supports developers to create and access SQLite databases inside applications. When we create a database, it will be used as a private component to serve only related applications.

There are many ways to use SQLite database in Android applications. It is recommended that you use the class that extends SQLiteOpenHelper to achieve this requirement. In this class, we need to define database properties and create various class variables (including the database list name we defined and its SQL creation string). The specific code is as follows:

private static final String NOTE_TABLE_CREATE = 
    "CREATE TABLE Note (noteID INTEGER PRIMARY KEY AUTOINCREMENT, " +
    "noteTxt TEXT);";

The example given here only involves a very simple set of tables, which contains two columns, one column contains ID and the other contains text; both columns are used to record user annotation information. In the SQLiteOpenHelper class, you can override the onCreate method to create your own database. In other parts of the application, such as the Activity class, you can access the database through SQLiteOpenHelper, insert new records using the WritableDatabase method, query existing records using the getReadableDatabase method, and then display the results in the application UI.

When iterating over the query results, our application will use the Cursor class - this class will refer to each row in the result set in turn.

5. Internet data

Many applications use Internet data resources, and some applications are even basically composed of a set of interfaces and a large number of Web data sources. You can use the Internet connection on the user's device to store and retrieve data from the Web. This mechanism will work normally as long as the Internet connection is valid. In order to achieve this, we need to add the "android.permission.INTERNET" permission in our manifest file.

If we want our application to obtain data from the Internet, we must ensure that this process is separated from the main UI thread of the application. Using AsyncTask, you can obtain data from the web source through a background process, write the results to the UI after the data download is completed, and finally let the UI perform its functions normally.

You can also add an internal AsyncTask class to the Activity class and create an AsyncTask instance in the Activity when you need to get data. By introducing the doInBackground and onPostExecute methods in AsyncTask, you can retrieve the data obtained in the Activity and write it to the user interface.

Obtaining web data is a moderately difficult task in application development work. It is best to try it after you have mastered Android development knowledge. However, you may soon find that such a data acquisition mechanism is very suitable for many applications, because it can effectively utilize the connection resources of the user device. Both Java and Android provide related tools for processing returned structured data - such as JSON feeds.

in conclusion

In today's article, we have a basic understanding of the data storage solutions we need to come into contact with when developing Android applications. No matter which solution you finally choose, you should use actual needs as a reference standard, because different solutions are only suitable for specific needs. In the next part of this series of tutorials, we will explore how to connect physical devices to an installed Eclipse installation and learn how to create virtual devices. After this, we'll also explore how to make applications run on both types of devices. By the way, I would like to report to you that in two more articles, this series of tutorials will be completely over; in the last article, we will study common classes and the Android Activity life cycle to help you get ready to develop applications.

Guess you like

Origin blog.csdn.net/m0_69824302/article/details/132698882