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);

InputStream in=getResources().openRawResource(R.raw.word s); DocumentBuilder builder=DocumentBuilderFactory

.newInstance() .newDocumentBuilder(); Document doc=builder.parse(in, null); NodeList words=doc.getElementsByTagName("word");

items.add(((Element)words.item(i)).getAttribute("value"));

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.

StaticFileDemo lorem ipsum dolor amet consectetuer

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.

0 0

Post a comment