The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.


Resource Sets and Configurations

Devices sometimes change while users are using them, in ways that our application will care about:

In all of these cases, it is likely that we will want to change what resources we use. For example, our layout for a portrait screen may be too tall to use in landscape mode, so we would want to substitute in some other layout.

This chapter will explore how to provide alternative resources for these different scenarios — called “configuration changes” — and will explain what happens to our activities when the user changes the configuration while we are in the foreground.

What’s a Configuration? And How Do They Change?

Different pieces of Android hardware can have different capabilities, such as:

Some of these, in the eyes of the core Android team, might drive the selection of resources, like layouts or drawables. Different screen sizes might drive the choice of layout. Different screen densities might drive the choice of drawable (using a higher-resolution image on a higher-density device). These are considered part of the device’s “configuration”.

Other differences — ones that do not drive the selection of resources — are not part of the device’s configuration but merely are “features” that some devices have and other devices do not. For example, cameras and Bluetooth and WiFi are features.

Some parts of a configuration will only vary based on different devices. A screen will not change density on the fly, for example. But some parts of a configuration can be changed during operation of the device, such as orientation (portrait vs. landscape) or language. When a configuration switches to something else, that is a “configuration change”, and Android provides special support for such events to help developers adjust their applications to match the new configuration.

Configurations and Resource Sets

One set of resources may not fit all situations where your application may be used. One obvious area comes with string resources and dealing with internationalization (I18N) and localization (L10N). Putting strings all in one language works fine — probably at least for the developer — but only covers one language.

That is not the only scenario where resources might need to differ, though. Here are others:

  1. Screen orientation: is the screen in a portrait orientation? Landscape?
  2. Screen size: is this something sized like a phone? A tablet? A television?
  3. Screen density: how many dots per inch does the screen have? Will we need a higher-resolution edition of our icon so it does not appear too small?
  4. Keyboard: what keyboard does the user have (QWERTY, numeric, neither), either now or as an option?
  5. Other input: does the device have some other form of input, like a directional pad or click-wheel?

The way Android currently handles this is by having multiple resource directories, with the criteria for each embedded in their names.

Suppose, for example, you want to support strings in both English and Spanish. Normally, for a single-language setup, you would put your strings in a file named res/values/strings.xml. To support both English and Spanish, you could create two folders, res/values-en/ and res/values-es/, where the value after the hyphen is the ISO 639-1 two-letter code for the language you want. Your English-language strings would go in res/values-en/strings.xml and the Spanish ones in res/values-es/strings.xml. Android will choose the proper file based on the user’s device settings. Note that Android 5.0 added support for BCP 47 three-letter language and locale values.

However, the better approach is for you to consider some language to be your default, and put those strings in res/values/strings.xml. Then, create other resource directories for your translations (e.g., res/values-es/strings.xml for Spanish). Android will try to match a specific language set of resources; failing that, it will fall back to the default of res/values/strings.xml. This way, if your app winds up on a device with a language that you do not expect, you at least serve up strings in your chosen default language. Otherwise, if there is no such default, you will wind up with a ResourceNotFoundException, and your application will crash.

This, therefore, is the bedrock resource set strategy: have a complete set of resources in the default directory (e.g., res/layout/), and override those resources in other resource sets tied to specific configurations as needed (e.g., res/layout-land/).

Note that Android Studio has a translations editor to help you manage your string resources for your default language and whatever translations you are going to include in your app.

Screen Size and Orientation

The preview of this section is in the process of being translated from its native Klingon.

Coping with Complexity

The preview of this section is in an invisible, microscopic font.

Choosing The Right Resource

The preview of this section was the victim of a MITM ('Martian in the middle') attack.

API-Versioned Resources

The preview of this section apparently resembled a Pokémon.

Default Change Behavior

The preview of this section is being chased by zombies.

State Saving Scenarios

The preview of this section may contain nuts.

Your Options for Configuration Changes

The preview of this section is en route to Mars.

Blocking Rotations

The preview of this section apparently resembled a Pokémon.

And Now, a Word From the Android Project View

The preview of this section will not appear here for a while, due to a time machine mishap.

Configuration Challenges

The preview of this section may contain nuts.