Thursday, 29 July 2010 01:12

Compiled and Noncompiled Android Resources

Rate this item
(0 votes)
Android supports a number of other resources in addition to string resources and layout resources. The general process of creating and using these various resources is similar.

However, it is worthwhile to consider some differences. Android supports all these resources through XML files, bitmap files for images, and raw files (examples of which could include audio and video). Within the set of XML files, you’ll find two types: one gets compiled into binary format, and the other gets copied as is. The examples you have seen so far—the
string-resource XML files and the layout-resource XML files—get compiled into binary format before becoming part of the installable package. You can also place raw XML files in the /res/ xml/ subdirectory to have them compiled into binary format. But if you place files, including XML files, in the /res/raw/ directory instead, they don’t get compiled into binary format. You
must use explicit stream-based APIs to read these files.

As we mentioned in Table 2-1 in the previous chapter, resource files are housed in various subdirectories based on their type. Here are some important subdirectories in the /res folder and the types of resources they host:

• anim: Compiled animation files
• drawable: Bitmaps
• layout: UI/view definitions
• values: Arrays, colors, dimensions, strings, and styles
• xml: Compiled arbitrary raw XML files
• raw: Noncompiled raw files

The resource compiler in the Android Asset Packaging Tool (AAPT) compiles all the resources except the raw resources and places them into the final .apk file. This file, which contains the Android application’s code and resources, correlates to Java’s .jar file (“apk” stands for “Android Package”). The .apk file is what gets installed onto the device. In addition to gathering
raw assets into a final compressed file, the AAPT also parses resource definitions into binary asset data.

Enumerating Key Android Resources

Now that we’ve been through the basics of resources, we’ll enumerate some of the other key resources that Android supports, their XML representations, and the way they’re used in Java code. (You can use this section as a quick reference as you write resource files for each resource.) To start with, take a quick glance at the types of resources and what they are used
for .

Each of the resources specified in this table are further elaborated in the following sections with XML and Java code snippets.

Color resources

As you can do with string resources, you can use reference identifiers to indirectly reference colors. Doing this enables Android to localize colors and apply themes. Once you’ve defined and identified colors in resource files, you can access them in Java code through their IDs. Whereas string-resource IDs are available under the .R.string namespace, the
color IDs are available under the .R.color namespace. See Listing 3-3 for some examples of specifying color in an XML resource file.

Listing 3-3. XML Syntax for Defining Color Resources

#f00
#0000ff
#f0f0
#ffffff00


The entries in Listing 3-3 need to be in a file residing in the /res/values subdirectory. The name of the file is arbitrary, meaning the file name can be anything you choose. Listing 3-4 shows an example of using a color resource in Java code.

Listing 3-4. Color Resources in Java code
int mainBackGroundColor
= activity.getResources.getColor(R.color.main_back_ground_color);

Listing 3-5 shows how you would use a color resource in a view definition.

Listing 3-5. Using Colors in View Definitions


android:layout_height="wrap_content"
android:textColor="@color/ red"
android:text="Sample Text to Show Red Color"/>

More on String resources

We covered string resources briefly when we introduced resources at the beginning of this chapter. Let us revisit them in order to provide some more detail. We will show you how to define and use HTML strings, as well as how to substitute variables in string resources.

Let us start by showing how you can define normal strings, quoted strings, HTML strings, and substitutable strings in an XML resource file (see Listing 3-6).

Listing 3-6. XML Syntax for Defining String Resources


simple string
"quoted'string"
\"double quotes\"

hello %2$s java format string. %1$s again


Hello Slanted Android, You are bold.



This XML string-resource file needs to be in the /res/values subdirectory. The name of the file is arbitrary.

Notice how quoted strings need to be either escaped or placed in alternate quotes. The string definitions also allow standard Java string-formatting sequences.

Android also allows child XML elements such as , , and other simple text-formatting HTML within the node. You can use this compound HTML string to style the text before painting in a text view.
The Java examples in Listing 3-7 illustrate each usage.

Listing 3-7. Using String Resources in Java Code

//Read a simple string and set it in a text view
String simpleString = activity.getString(R.string.simple_string);
textView.setText(simpleString);
//Read a quoted string and set it in a text view
String quotedString = activity.getString(R.string.quoted_string);
textView.setText(quotedString);
//Read a double quoted string and set it in a text view
String doubleQuotedString = activity.getString(R.string.double_quoted_string);
textView.setText(doubleQuotedString);
//Read a Java format string
String javaFormatString = activity.getString(R.string.java_format_string);
//Convert the formatted string by passing in arguments
String substitutedString = String.format(javaFormatString, "Hello" , "Android");
//set the output in a text view
textView.setText(substitutedString);

//Read an html string from the resource and set it in a text view
String htmlTaggedString = activity.getString(R.string.tagged_string);
//Convert it to a text span so that it can be set in a text view
//android.text.Html class allows painting of "html" strings
//This is strictly an Android class and does not support all html tags
Spanned textSpan = android.text.Html.fromHtml(htmlTaggedString);
//Set it in a text view
textView.setText(textSpan);

Once you’ve defined the strings as resources, you can set them directly on a view such as TextView in the XML layout definition for that TextView. Listing 3-8 shows an example where an HTML string is set as the text content of a TextView.

Listing 3-8. Using String Resources in XML


android:layout_height="wrap_content"
android:textAlign="center"
android:text="@string/tagged_string"/>

TextView automatically realizes that this string is an HTML string, and honors its formatting accordingly. This is nice because you can quickly set attractive text in your views as part of the layout.

Dimension resources

Pixels, inches, and points are all examples of dimensions that can play a part in XML layouts or Java code. You can use these dimension resources to style and localize Android UIs without changing the source code.

Listing 3-9 shows how you can use dimension resources in XML.

Listing 3-9. XML Syntax for Defining Dimension Resources


1px
5dp
100sp

You could specify the dimensions in any of the following units:
• px: Pixels
• in: Inches
• mm: Millimeters
• pt: Points
• dp: Density-independent pixels based on a 160-dpi (pixel density per inch) screen
(dimensions adjust to screen density)
• sp: Scale-independent pixels (dimensions that allow for user sizing; helpful for use in
fonts)

In Java, you need to access your Resources object instance to retrieve a dimension. You can do this by calling getResources on an activity object (see Listing 3-10).

Listing 3-10. Using Dimension Resources in Java Code

float dimen = activity.getResources().getDimension(R.dimen.mysize_in_pixels);

As in Java, the resource reference for a dimension in XML uses dimen as opposed to the full word “dimension” (see Listing 3-11).

Listing 3-11. Using Dimension Resources in XML

android:layout_height="wrap_content"
android:textSize="@dimen/medium_size"/>

Image resources

Android generates resource IDs for image files placed in the /res/drawable subdirectory. The supported image types include .gif, .jpg, and .png. Each image file in this directory generates a unique ID from its base file name. If the image file name is sample_image.jpg, for example, then the resource ID generated will be R.drawable.sample_image.

You can then reference these images in other XML layout definitions, as shown in Listing 3-12.

Listing 3-12. Using Image Resources in XML

android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Dial"
android:background="@drawable/sample_image"
/>

You can also retrieve the image programmatically and set it yourself in Java (see Listing 3-13).

Listing 3-13. Using Image Resources in Java

//Call getDrawable to get the image
BitmapDrawable d = activity.getResources().getDrawable(R.drawable.sample_image);
//You can use the drawable then to set the background
button.setBackgroundDrawable(d);
//or you can set the background directly from the Resource Id
button.setBackgroundResource(R.drawable.icon);

Android also supports a special type of image called a stretchable image. This is simply a kind of .png where parts of the image can be specified as static and stretchable. Android provides a tool called the Draw 9-patch tool to specify these regions. (You can read more about it at http://developer.android.com/guide/developing/tools/draw9patch.html.) Once the .png image is made available, you can use it as any other image. It comes in handy when used as background for buttons where the button has to stretch itself to accommodate the text.

Color-Drawable resources

In Android, an image is one type of a drawable resource. Android supports another drawable resource called a color-drawable resource; it’s essentially a colored rectangle.

To define one of these color rectangles, you define an XML element by the node name of drawable in any XML file in the /res/values subdirectory. Listing 3-14 shows a couple of colordrawable resource examples.

Listing 3-14. XML Syntax for Defining Color-Drawable Resources


#f00
#0000ff
#f0f0


Listings 3-15 and 3-16 show how you can use a color-drawable resource in Java and XML,
respectively.

Listing 3-15. Using Color-Drawable Resources in Java Code

// Get a drawable
ColorDrawble redDrawable =
(ColorDrawable)
activity.getResources().getDrawable(R.drawable.red_rectnagle);
//Set it as a background to a text view
textView.setBackground(redDrawable);

Listing 3-16. Using Color-Drawable Resources in XML Code


android:layout_height="wrap_content"
android:textAlign="center"
android:background="@drawable/red_rectangle"/>
To achieve the rounded corners in your drawable, you can use the currently undocumented
tag. However, this tag needs to reside in a file by itself in the /res/drawable
directory. Listing 3-17 shows how you can use the tag to define a rounded rectangle in
a file called /res/drawable/my_rounded_rectangle.xml.

Listing 3-17. Defining a Rounded Rectangle






android:right="10dp" android:bottom="10dp" />


You can then use this drawable resource as a background of the previous text-view
example:

// Get a drawable
GradientDrawable roundedRectangle =
(GradientDrawable)
activity.getResources().getDrawable(R.drawable.red_rectnagle);
//Set it as a background to a text view
textView.setBackground(roundedRectangle);

Working with Arbitrary XML Resource Files

Android also allows arbitrary XML files as resources. This approach offers three distinct advantages. First, it provides a quick way to reference these files based on their generated resource IDs. Second, the approach allows you to localize these resource XML files. Third, you can compile and store these XML files on the device efficiently.

XML files that need to be read in this fashion are stored under the /res/xml subdirectory. Here is an example XML file called /res/xml/test.xml:

<rootelem1>
<subelem1>
Hello World from an xml sub element
</subelem1>
</rootelem1>

As it does with other Android XML resource files, the AAPT will compile this XML file before placing it in the application package. You will need to use an instance of XmlPullParser if you want to parse these files. You can get an instance of the XmlPullParser implementation using this code from any context (including activity):

Resources res = activity.getResources();
XmlResourceParser xpp = res.getXml(R.xml.test);

The returned XmlResourceParser is an instance of XmlPullParser, and it also implements java.util.AttributeSet. Listing 3-18 shows a more complete code snippet that reads the test.xml file.

Listing 3-18. Using XmlPullParser

private String getEventsFromAnXMLFile(Activity activity)
throws XmlPullParserException, IOException

{
StringBuffer sb = new StringBuffer();
Resources res = activity.getResources();
XmlResourceParser xpp = res.getXml(R.xml.test);
xpp.next();
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT)
{
if(eventType == XmlPullParser.START_DOCUMENT)
{
sb.append("******Start document");
}
else if(eventType == XmlPullParser.START_TAG)
{
sb.append("\nStart tag "+xpp.getName());
}
else if(eventType == XmlPullParser.END_TAG)
{
sb.append("\nEnd tag "+xpp.getName());
}
else if(eventType == XmlPullParser.TEXT)
{
sb.append("\nText "+xpp.getText());
}
eventType = xpp.next();
}//eof-while
sb.append("\n******End document");
return sb.toString();
}//eof-function

In Listing 3-18, you can see how to get XmlPullParser, how to use XmlPullParser to navigate the XML elements in the XML document, and how to use additional methods of XmlPullParser to access the details of the XML elements. If you want to run this code, you must create an XML file as shown earlier and call the getEventsFromAnXMLFile function from any menu item or button click. It will return a string, which you can print out to the log stream using the Log.d debug method.

Working with Raw Resources

Android also allows raw files in addition to raw XML files. These raw resources, placed in /res/ raw, are arbitrary file resources such as audio, video, or text files that require localization or references through resource IDs. Unlike the raw XML files placed in /res/xml, these files are not compiled but moved to the application package as is. However, each file will have an identifier
generated in R.java. If you were to place a text file at /res/raw/test.txt, you would be able to  read that file using the code in Listing 3-19.

Listing 3-19. Reading a Raw Resource

String getStringFromRawFile(Activity activity)
{
Resources r = activity.getResources();
InputStream is = r.openRawResource(R.raw.test);
String myText = convertStreamToString(is);
is.close();
return myText;
}
String convertStreamToString(InputStream is)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i = is.read();
while (i != -1)
{
baos.write(i);
i = baos.read();
}
return baos.toString();
}

Working with Assets

Android offers one more directory where you can keep files to be included in the package:/assets. It’s at the same level as /res, meaning it’s not part of the /res subdirectories. The files in /assets do not generate IDs in R.java; you must specify the file path to read them. The file path is a relative path starting at /assets. You will use the AssetManager class to access these files:

//Note: Exceptions are not shown in the code
String getStringFromAssetFile(Activity activity)
{
AssetManager am = activity.getAssets();
InputStream is = am.open("test.txt");
String s = convertStreamToString(is);
is.close();
return s;
}

Reviewing the Resources Directory Structure

In summary, here is a quick look at the overall resources directory structure:

/res/values/strings.xml
/colors.xml
/dimens.xml
/attrs.xml
/styles.xml
/drawable/*.png
/*.jpg
/*.gif
/*.9.png
/anim/*.xml
/layout/*.xml
/raw/*.*
/xml/*.xml
/assets/*.*/*.*

Let us conclude this section on resources by quickly enumerating what you have learned about resources so far. You know the types of resources supported in Android and you know how to create these resources in XML files. You know how resource IDs are generated and how to use them in Java code. You also learned that resource ID generation is a convenient scheme
that simplifies resource usage in Android. Finally, you learned how to work with raw resources and assets. With that, we will now turn our attention to the section on content providers, where you will learn to work with data on Android.









Last modified on Thursday, 29 July 2010 01:43
John

John


E-mail: This e-mail address is being protected from spambots. You need JavaScript enabled to view it