One poor coding practice that really gets our blood boiling is when developers include raw string content inline in code. Sure, there are occasionally good reasons to do this, especially when writing debug code, but generally speaking, if your Android application relies on string content that is displayed on the screen, this data belongs in the Android resources, not in the code itself.
There are a number of benefits to including string content as a resource, such as:
- It centralizes the strings used by the application in a single location that is easily managed (by the developer or a non-developer).
- Strings can be defined as a resource once, and used throughout the code. Therefore, it will have consistent spelling, case and punctuation.
- Strings can be internationalized easily, allowing your application to support multiple languages with a single application package file (APK).
- Strings don’t clutter up your application code, leaving it clear and easy to maintain.
So let’s talk about how to add strings and more importantly, string array resources to your applications effectively.
Step 1: Define String Resources for Individual Strings
String resources belong in the /res/values/strings.xml file. Define a string resource entry for each string used by your application. Name your string resources appropriately. For example, the following XML excerpt defines a number of game character race types as individual strings:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Choose Your Own</string> <string name="race_orc">Orc</string> <string name="race_elf">Elf</string> <string name="race_troll">Troll</string> <string name="race_human">Human</string> <string name="race_halfling">Halfling</string> <string name="race_goblin">Goblin</string> </resources>
Note the “race_” prefix of each string resource. This helps remind team members that these strings may be related somehow. For example, they might be used together an array or displayed as options in a Spinner control.
Step 2: Load Your String Resources Programmatically
You can easily load a string to use in your code using the getString() method of the Resources class. The following code can be dropped into your Activity class to load a String resource defined in your application:
String sOrc = getResources().getString(R.string.race_orc);
The handy thing about loading resources this way is that if you’ve provided alternative resources in different languages, the appropriate language version of the string will be loaded based upon the device settings at runtime. No special code is needed for this to work.
Step 3: Define String Array Resources Using String Resource References
Now let’s say you wanted to create an array of those character race strings. Sure, you could load them all up individually in the Java code and make a String array in memory, but you would need to know each of the resource’s full id names and reference it in the code. Instead, your best bet is to create a string array resource that references the individual string resources you’ve already created, tying them together.
String array resources are best stored in the /res/values/arrays.xml file. Define a string array with an item for each string used by your application. Name your string array resources appropriately. For example, the following XML excerpt defines an array that contains each of the game character race types defined in the strings.xml resource file in Step 1:
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="races_array"> <item>@string/race_goblin</item> <item>@string/race_orc</item> <item>@string/race_elf</item> <item>@string/race_human</item> <item>@string/race_troll</item> <item>@string/race_halfling</item> </string-array> </resources>
Step 4: Load Your String Array Resources Programmatically
You can easily load a string array to use in your code using the getStringArray() method of the Resources class. The following code can be dropped into your Activity class to load an array resource defined in your application:
String[] cRaces = getResources().getStringArray(R.array.races_array);
Step 5: Referencing Array Resources in Simple Spinner Controls
One useful reason to go through all this work is to populate a control that requires a data adapter, the simplest of which is an array. If you are unfamiliar with using data adapters to populate Spinner controls and the like, check out the Android Developer website’s Hello Spinner tutorial. However, the method described in the linked tutorial is not as easily internationalized as what we are describing in this quick tut, since it defines the raw string contents in the string array resource, instead of as string references.
Using string array resources allows you to skip the steps of hooking up your data adapter to your control. For example, a simple Spinner control, or dropdown, can be populated with a string array resource without bothering with pesky adapters. You simply add a Spinner control to your layout file and set its android:entries attribute to the string array you created and you’re done. For example:
<Spinner android:layout_height="wrap_content" android:layout_width="match_parent" android:id="@+id/spinnerOfCharacterRaces" android:entries="@array/races_array"> </Spinner>
This defines a Spinner control that will show each of the character race strings as options, as shown in Figure 1.
In your Activity class, you can now implement an OnItemSelectedListener to capture when the user selects a specific character race, like this:
Spinner cRaceSpinner = (Spinner) findViewById(R.id.spinnerOfCharacterRaces); cRaceSpinner.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView<?> arg0, View arg1,arg2, long arg3) { String strChosenRace = (String) arg0.getItemAtPosition(arg2); } public void onNothingSelected(AdapterView<?> arg0) {} });
Here we simply react whenever an item in the Spinner is selected. We look up the data selected using the getItemAtPosition() method, which, in the case of a string array resource, is the string data itself.
Conclusion
There’s absolutely no reason to define strings and arrays of strings inline in code. Strings and string arrays belong in your Android application resources, not cluttering up your elegant Java. There are a number of benefits to storing string data in resource files, including better organization and easier internationalization. String arrays are even more powerful when they are comprised of string resource references instead of the raw string data. String array resources can be glued to many UI controls that generally rely upon data adapters without a lot of fuss, making your code even more readable and maintainable.
As always, we look forward to your feedback.
About the Authors
Mobile developers Lauren Darcey and Shane Conder have coauthored several books on Android development: an in-depth programming book entitled Android Wireless Application Development, Second Edition and Sams Teach Yourself Android Application Development in 24 Hours, Second Edition. When not writing, they spend their time developing mobile software at their company and providing consulting services. They can be reached at via email to [email protected], via their blog at androidbook.blogspot.com, and on Twitter @androidwireless.
Comments