Книга: Beginning Android
You and the Horse You Rode in On
You and the Horse You Rode in On
Let’s suppose you have some static data you want to ship with the application, such as a list of words for a spell-checker. The easiest way to deploy that is to put the file in the res/raw directory, so it gets put in the Android application APK file as part of the packaging process as a raw resource.
To access this file, you need a Resources
object. From an activity, that is as simple as calling getResources()
. A Resources
object offers openRawResource()
to get an InputStream
on the file you specify. Rather than a path, openRawResource()
expects an integer identifier for the file as packaged. This works just like accessing widgets via findViewById()
— if you put a file named words.xml
in res/raw
, the identifier is accessible in Java as R.raw.words
.
Since you can get only an InputStream
, you have no means of modifying this file. Hence, it is really useful only for static reference data. Moreover, since it is unchanging until the user installs an updated version of your application package, either the reference data has to be valid for the foreseeable future, or you need to provide some means of updating the data. The simplest way to handle that is to use the reference data to bootstrap some other modifiable form of storage (e.g., a database), but this makes for two copies of the data in storage. An alternative is to keep the reference data as is but keep modifications in a file or database, and merge them together when you need a complete picture of the information. For example, if your application ships a file of URLs, you could have a second file that tracks URLs added by the user or reference URLs that were deleted by the user.
In the Files/Static
sample project available in the Source Code section of http://apress.com, you will find a reworking of the listbox example from Chapter 8, this time using a static XML file instead of a hard-wired array in Java. The layout is the same:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="@+id/selection"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false"
/>
</LinearLayout>
In addition to that XML file, you need an XML file with the words to show in the list:
<words>
<word value="lorem" />
<word value="ipsum" />
<word value="dolor" />
<word value="sit" />
<word value="amet" />
<word value="consectetuer" />
<word value="adipiscing" />
<word value="elit" />
<word value="morbi" />
<word value="vel" />
<word value="ligula" />
<word value="vitae" />
<word value="arcu" />
<word value="aliquet" />
<word value="mollis" />
<word value="etiam" />
<word value="vel" />
<word value="erat" />
<word value="placerat" />
<word value="ante" />
<word value="porttitor" />
<word value="sodales" />
<word value="pellentesque" />
<word value="augue" />
<word value="purus" />
</words>
While this XML structure is not exactly a model of space efficiency, it will suffice for a demo.
The Java code now must read in that XML file, parse out the words, and put them someplace for the list to pick up:
public class StaticFileDemo extends ListActivity {
TextView selection;
ArrayList<String> items = new ArrayList<String>();
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
selection = (TextView)findViewById(R.id.selection);
try {
InputStream in = getResources().openRawResource(R.raw.words);
DocumentBuilder builder = DocumentBuilderFactory
.newInstance().newDocumentBuilder();
Document doc = builder.parse(in, null);
NodeList words = doc.getElementsByTagName("word");
for (int i=0; iwords.getLength(); i++) {
items.add(((Element)words.item(i)).getAttribute("value"));
}
in.close();
} catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), 2000).show();
}
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, items));
}
public void onListItemClick(ListView parent, View v, int position,
long id) {
selection.setText(items.get(position).toString());
}
}
The differences between the Chapter 8 example and this one mostly lie within onCreate()
. We get an InputStream
for the XML file (getResources().openRawResource(R.raw.words)
), then use the built-in XML parsing logic to parse the file into a DOM Document, pick out the word elements, then pour the value attributes into an ArrayList
for use by the ArrayAdapter
.
The resulting activity looks the same as before (Figure 18-1), since the list of words is the same, just relocated.
Figure 18-1. The StaticFileDemo sample application
Of course, there are even easier ways to have XML files available to you as pre-packaged files, such as by using an XML resource. That is covered in the next chapter. However, while this example uses XML, the file could just as easily have been a simple one-word-per-line list, or in some other format not handled natively by the Android resource system.
- Разработка приложений баз данных InterBase на Borland Delphi
- 4.4.4 The Dispatcher
- Open Source Insight and Discussion
- Introduction to Microprocessors and Microcontrollers
- About the author
- Chapter 6. Traversing of tables and chains
- Chapter 7. The state machine
- Chapter 8. Saving and restoring large rule-sets
- Chapter 11. Iptables targets and jumps
- Chapter 12. Debugging your scripts
- Chapter 5 Installing and Configuring VirtualCenter 2.0
- Chapter 16. Commercial products based on Linux, iptables and netfilter