Show navigation Hide navigation

Optimizing Apps for Android 3.0

This document has been deprecated.

To learn about how you can optimize your app for both tablets and handsets, please read the guide to Supporting Tablets and Handsets.

Android 3.0 introduces several features that allow you to enhance your user's experience on tablets and similar devices. Any application you've already published is compatible with devices running Android 3.0, by default, because Android applications are forward-compatible. However, new tablet devices running Android 3.0 are now available to the public and provide users a new Android experience on a larger screen, so you should make sure your application looks and works great on the new platform and new device form-factors.

This document shows how you can optimize your existing application for Android 3.0 and maintain compatibility with older versions or upgrade your application completely with new APIs.

To get started:

  1. Set up your SDK with Android 3.0.

    Install the Android 3.0 platform, new tools, and set up a new AVD.

  2. Choose to either optimize or upgrade:
    1. Optimize your app for tablets and similar devices.

      Read this section if you have an existing application and want to maintain compatibility with older versions of Android. All you need to do is update your manifest file to declare support for Android 3.0, test your application on the new platform, and add extra resources to support extra large screens, as appropriate.

    2. Upgrade or develop a new app for tablets and similar devices.

      Read this section if you want to upgrade your application to use APIs introduced in Android 3.0 or create a new application targeted to tablets and similar devices. Compared to upgrading to previous versions of Android, there's nothing different about upgrading to Android 3.0. This section introduces some of the key features and APIs you should use to make an application that's fully enhanced for tablets.

  3. Consider whether you need to manage the distribution of your application based on screen configuration.
  4. Then review some other issues you might encounter when developing for tablets and similar devices.

Set Up Your SDK with Android 3.0

To start testing and developing your application on Android 3.0, set up your existing Android SDK with the new platform:

(If you don't have an existing Android SDK, download the SDK starter package now.)

  1. Launch the Android SDK Manager and install the following:
    • SDK Platform Android 3.0
    • Android SDK Tools, revision 10
    • Android SDK Platform-tools, revision 3
    • Documentation for Android SDK, API 11
    • Samples for SDK API 11
  2. Create an AVD for a tablet-type device:

    Set the target to "Android 3.0" and the skin to "WXGA" (the default skin).

The best way to test your application on Android 3.0 is to use real hardware running Android 3.0, such as the Motorola Xoom. Of course, you can also use the Android emulator on your development machine, but because the Android emulator must simulate the ARM instruction set on your computer and the WXGA screen is significantly larger than a typical virtual device, emulator performance is much slower than a real device.

About emulator performance

Initializing the emulator can be slow and can take several minutes, depending on your hardware. When the emulator is booting, there is limited user feedback, so please be patient and wait until you see the home screen (or lock screen) appear.

However, you don't need to boot the emulator each time you rebuild your application—typically you only need to boot at the start of a session and keep it running. Also see the tip below for information about using a snapshot to drastically reduce startup time after the first initialization.

General performance in the emulator is also slow. We're working hard to resolve the performance issues and it will improve in future tools releases. If you don't yet have a real device running Android 3.0, the emulator is still best way to evaluate your application's appearance and functionality on Android 3.0.

Tip: To improve the startup time for the emulator, enable snapshots for the AVD when you create it with the AVD Manager (there's a checkbox in the AVD creator to Enable snapshots). Then, start the AVD from the AVD manager and check Launch from snapshot and Save to snapshot. This way, when you close the emulator, a snapshot of the AVD state is saved and used to quickly relaunch the AVD next time. However, when you choose to save a snapshot, the emulator will be slow to close, so you might want to disable Save to snapshot after you've acquired an initial snapshot (after you close the AVD for the first time).

Optimizing Your App for Tablets

If you've already developed an application for an earlier version of Android, there are a few things you can do to optimize it for a tablet-style experience on Android 3.0 without changing the minimum version required (you don't need to change your manifest's android:minSdkVersion).

Note: All Android applications are forward-compatible, so there's nothing you have to do—if your application is a good citizen of the Android APIs, your app should work fine on devices running Android 3.0. However, in order to provide users a better experience when using your app on an Android 3.0 tablet or similar-size device, you should update your application to inherit the new system theme and provide some optimizations for larger screens.

Here are a few things you can do to optimize your application for devices running Android 3.0:

  1. Test your current application on Android 3.0
    1. Build your application as-is and install it on your Android 3.0 AVD (created above during setup).
    2. Perform your usual tests to be sure everything works and looks as expected.
  2. Apply the new "holographic" theme to your application
    1. Open your manifest file and update the <uses-sdk> element to set android:targetSdkVersion to "11". For example:
      <manifest ... >
          <uses-sdk android:minSdkVersion="4" 
                    android:targetSdkVersion="11" />
          <application ... >
              ...
          <application>
      </manifest>
      

      By targeting the Android 3.0 platform, the system automatically applies the holographic theme to each activity when your application runs on an Android 3.0 device. The holographic theme provides a new design for widgets, such as buttons and text boxes, and new styles for other visual elements. This is the standard theme for applications built for Android 3.0, so your application will look and feel consistent with the system and other applications when it is enabled.

      Additionally, when an activity uses the holographic theme, the system enables the Action Bar for the activity and removes the Options Menu button in the system bar. The Action Bar replaces the traditional title bar at the top of the activity window and provides the user access to the activity's Options Menu.

    2. Build your application against the same version of the Android platform you have been using previously (such as the version declared in your android:minSdkVersion), but install it on the Android 3.0 AVD. (You should not build against Android 3.0 unless you are using new APIs.) Repeat your tests to be sure that your user interface works well with the holographic theme.

      Note: If you have applied other themes directly to your activities, they will override the inherited holographic theme. To resolve this, you can use the platform version qualifier to provide an alternative theme for Android 3.0 devices that's based on the holographic theme. For more information, read how to select a theme based on platform version.

  3. Supply alternative layout resources for xlarge screens

    By providing alternative resources when running on extra large screens (using the xlarge resource qualifier), you can improve the user experience of your application on tablet-type devices without using new APIs.

    For example, here are some things to consider when creating a new layout for extra large screens:

    • Landscape layout: The "normal" orientation for tablet-type devices is usually landscape (wide), so you should be sure that your activities offer a layout that's optimized for a wide viewing area.

      You can specify landscape resources with the land resource qualifier, but if you want alternative resources for an extra large landscape screen, you should use both the xlarge and land qualifiers. For example, res/layout-xlarge-land/. The order of the qualifier names is important; see Providing Alternative Resources for more information.

    • Button position and size: Consider whether the position and size of the most common buttons in your UI make them easily accessible while holding a tablet with two hands. In some cases, you might need to resize buttons, especially if they use "wrap_content" as the width value. To enlarge the buttons, if necessary, you should either: add extra padding to the button; specify dimension values with dp units; or use android:layout_weight when the button is in a linear layout. Use your best judgment of proportions for each screen size—you don't want the buttons to be too big, either.
    • Font sizes: Be sure your application uses sp units when setting font sizes. This alone should ensure a readable experience on tablet-style devices, because it is a scale-independent pixel unit, which will resize as appropriate for the current screen configuration. In some cases, however, you still might want to consider larger font sizes for xlarge configurations.

    In general, always be sure that your application follows the Best Practices for Screen Independence.

Upgrading or Developing a New App for Tablets

If you want to develop an application that's fully enhanced for tablet-type devices running Android 3.0, then you need to use new APIs in Android 3.0. This section introduces some of the new features you should use.

Declare the minimum system version

The first thing to do when you upgrade or create a project for Android 3.0 is set your manifest's android:minSdkVersion to "11". This declares that your application uses APIs available in Android 3.0 and greater, so it should not be available to devices running an older version of Android. For example:

<manifest ... >
    <uses-sdk android:minSdkVersion="11" />
    <application ... >
        ...
    <application>
</manifest>

Not only is this necessary in order to declare the minimum API level your application requires, but it enables the new holographic theme to each of your activities. The holographic theme is the standard theme for the Android 3.0 system and all applications designed for it. It includes new designs for the system widgets and overall appearance.

Additionally, the holographic theme enables the Action Bar for each activity.

Use the Action Bar

The Action Bar is a widget for activities that replaces the traditional title bar at the top of the screen. By default, the Action Bar includes the application logo on the left side, followed by the activity title, and access to items from the Options Menu in a drop-down list on the right side.

You can enable items from the Options Menu to appear directly in the Action Bar as "action items" by adding showAsAction="ifRoom" to specific menu items in your menu resource. You can also add navigation features to the Action Bar, such as tabs, and use the application icon to navigate to your application's "home" activity or to navigate "up" the application's activity hierarchy.

For more information, read Using the Action Bar.

Divide your activities into fragments

A fragment represents a behavior or a portion of user interface in an activity. You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running. Fragments are an optional component for your activities that allow you to build a multi-pane UI and reuse them in multiple activities. If you're building an application for tablets, we recommend that you use fragments to create activities that offer a more dynamic and flexible user interface.

For example, a news application can use one fragment to show a list of articles on the left and another fragment to display an article on the right—both fragments appear in one activity, side by side, and each fragment has its own set of lifecycle callback methods and handles its own input events. Thus, instead of using one activity to select an article and another activity to read the article, the user can select an article and read it all within the same activity.

For more information, read the Fragments document.

Use new animation APIs for transitions

An all-new animation framework allows you to animate arbitrary properties of any object (such as a View, Drawable, Fragment, or anything else). You can define several animation aspects (such as duration, repeat, interpolation, and more) for an object's int, float, and hexadecimal color values, by default. That is, when an object has a property field for one of these types, you can change its value over time to affect an animation.

The View class also provides new APIs that leverage the new animation framework, allowing you to easily apply 2D and 3D transformations to views in your activity layout. New transformations are made possible with a set of object properties that define the view's layout position, orientation, transparency and more.

For more information, read the Property Animation document.

Enable hardware acceleration

Android 3.0 adds a hardware-accelerated OpenGL renderer that gives a performance boost to most 2D graphics operations. You can enable hardware-accelerated rendering in your application by setting android:hardwareAccelerated="true" in your manifest's <application> element or for individual <activity> elements. Hardware acceleration results in smoother animations, smoother scrolling, and overall better performance and response to user interaction. When enabled, be sure that you thoroughly test your application on a device that supports hardware acceleration.

Enhance your app widgets

App widgets allow users to access information from your application directly from the Home screen and interact with ongoing services (such as preview their email and control music playback). Android 3.0 enhances these capabilities by enabling collections, created with widgets such as ListView, GridView, and the new StackView. These widgets allow you to create more interactive app widgets, such as one with a scrolling list, and can automatically update their data through a RemoteViewsService.

Additionally, you should create a preview image of your app widget using the Widget Preview application (pre-installed in an Android 3.0 AVD) and reference it with the android:previewImage attribute, so that users can see what the app widget looks like before adding it to their Home screen.

Add other new features

Android 3.0 introduces many more APIs that you might find valuable for your application, such as drag and drop APIs, new Bluetooth APIs, a system-wide clipboard framework, a new graphics engine called Renderscript, and more.

To learn more about the APIs mentioned above and more, see the Android 3.0 Platform document.

Look at some samples

Many of the new features and APIs that are described above and in the Android 3.0 Platform document also have accompanying samples that allow you to preview the effects and can help you understand how to use them. To get the samples, download them from the SDK repository using the Android SDK Manager. After downloading the samples ("Samples for SDK API 11"), you can find them in <sdk_root>/samples/android-11/. The following list provides links to the browsable source code for some of the samples:

  • Honeycomb Gallery: Demonstrates many new APIs in Android 3.0, including fragments, the action bar, drag and drop, and animations.
  • Fragments: Various samples that demonstrate fragment layouts, back stack, restoring state, and more.
  • Action Bar: Samples that demonstrate various Action Bar features, such as tabs, logos, and action items.
  • Clipboard: An example of how to use the clipboard for copy and paste operations.
  • Drag and Drop: An example of how to perform drag and drop with new View events.
  • Multi-choice List: An example of how to provide multiple-choice selection for ListView and GridView.
  • Content Loaders: An example using new Loader APIs to asynchronously load data.
  • Property Animation: Several samples using the new animation APIs to animate object properties.
  • Search View Widget: Example using the new search widget in the Action Bar (as an "action view").
  • Renderscript: Contains several different applications that demonstrate using renderscript APIs for computations and 3D graphics.

Managing App Distribution Based on Screen Configuration

If your manifest file has either android:minSdkVersion or android:targetSdkVersion set to "4" or higher, then the Android system will scale your application's layout and assets to fit the current device screen, whether the device screen is smaller or larger than the one for which you originally designed your application. As such, you should always test your application on real or virtual devices with various screen sizes and densities.

Although we recommend that you design your application to function properly on multiple configurations of screen size and density, you can instead choose to limit the distribution of your application to certain types of screens, such as only tablets or only mobile devices. To do so, you can add elements to your Android manifest file that enable filtering based on screen configuration by external services such as Google Play.

However, before you decide to restrict your application to certain screen configurations, you should understand the techniques for supporting multiple screens and employ them to the best of your ability. By supporting multiple screens, your application can be made available to the greatest number of users with different devices.

Filtering a tablet application from mobile devices

If the system scaling adversely affects your application UI when scaling your application down for smaller screens, you should add alternative layouts for smaller screens to adjust your layout. However, sometimes your layout still might not fit a smaller screen or you've explicitly designed your application only for tablets and other large devices. In this case, you can manage the availability of your application to smaller screens by using the <supports-screens> manifest element.

For example, if you want your application to be available only to extra large screens, you can declare the element in your manifest like this:

<manifest ... >
    ...
    <supports-screens android:smallScreens="false"
                      android:normalScreens="false"
                      android:largeScreens="false"
                      android:xlargeScreens="true" />
    <application ... >
        ...
    <application>
</manifest>

External services such as Google Play read this manifest element and use it to ensure that your application is available only to devices with an extra large screen.

Note: If you use the <supports-screens> element for the reverse scenario (when your application is not compatible with larger screens) and set the larger screen size attributes to "false", then external services such as Google Play do not apply filtering. Your application will still be available to larger screens, but when it runs, it will not fill the screen—the system will draw it in a "postage stamp" window that's the same relative size as the screen size that your application does support. If you want to prevent your application from being downloaded on larger screens, see the following section.

Filtering a mobile device application from tablets

Because Android automatically scales applications to fit larger screens, you shouldn't need to filter your application from larger screens. However, you might discover that your application can't scale up or perhaps you've decided to publish two versions of your application that each deliver different features for different screen configurations, so you don't want larger devices to download the version designed for smaller screens. In such a case, you can use the <compatible-screens> element to manage the distribution of your application based on the combination of screen size and density. External services such as Google Play uses this information to apply filtering to your application, so that only devices that have a screen configuration with which you declare compatibility can download your application.

The <compatible-screens> element must contain one or more <screen> elements, which each specify a screen configuration with which your application is compatible, using both the android:screenSize and android:screenDensity attributes. Each <screen> element must include both attributes to specify an individual screen configuration—if either attribute is missing, then the element is invalid (external services such as Google Play will ignore it).

For example, if your application is compatible with only small and normal screens, regardless of screen density, then you must specify eight different <screen> elements, because each screen size has four density configurations. You must declare each one of these; any combination of size and density that you do not specify is considered a screen configuration with which your application is not compatible. Here's what the manifest entry looks like if your application is compatible with only small and normal screens:

<manifest ... >
    ...
    <compatible-screens>
        <!-- all small size screens -->
        <screen android:screenSize="small" android:screenDensity="ldpi" />
        <screen android:screenSize="small" android:screenDensity="mdpi" />
        <screen android:screenSize="small" android:screenDensity="hdpi" />
        <screen android:screenSize="small" android:screenDensity="xhdpi" />
        <!-- all normal size screens -->
        <screen android:screenSize="normal" android:screenDensity="ldpi" />
        <screen android:screenSize="normal" android:screenDensity="mdpi" />
        <screen android:screenSize="normal" android:screenDensity="hdpi" />
        <screen android:screenSize="normal" android:screenDensity="xhdpi" />
    </compatible-screens>
    <application ... >
        ...
    <application>
</manifest>

Note: Although you can also use the <compatible-screens> element for the reverse scenario (when your application is not compatible with smaller screens), it's easier if you instead use the <supports-screens> as discussed in the previous section, because it doesn't require you to specify each screen density your application supports.

Remember, you should strive to make your application available to as many devices as possible by applying all necessary techniques for supporting multiple screens. You should then use the <compatible-screens> element to filter your application from certain devices only when you cannot offer compatibility on all screen configurations or you have decided to provide multiple versions of your application, each for a different set of screen configurations.

Other Issues

Whether you decide to optimize or upgrade your application for tablet-type devices, you should be aware that the functionality and availability of your application on new devices might be affected by the following issues:

  • Tablets are often designed for use in the landscape orientation

    Tablets and similar devices often have a screen that uses the landscape orientation by default. If your application assumes a portrait orientation or locks into portrait orientation, you should update your application to support landscape.

  • Not all devices have telephony or other features

    If your application declares the "android.hardware.telephony" feature in the manifest, then it will not be available to devices that do not offer telephony (such as tablets), based on Google Play filtering. If your application can function properly without telephony, you should update your application to gracefully disable the telephony features when not available on a device.

Adding support for landscape screens

Although tablets can rotate to operate in any orientation, they are often designed for landscape orientation and that is how most users will use them. So, you should ensure that your application can function in landscape. Even if you want to avoid rotating the screen while your application is running, you should not assume that portrait is the device's default orientation. You should either ensure that your layout is usable in both portrait and landscape orientations or provide an alternative layout resource for landscape orientation.

If you believe your application or game provides its best experience when the screen is tall, consider that tablets and similar devices have a screen that's as tall or taller in landscape orientation than a phone in portrait orientation. With that in mind, you might be able to add a landscape design that adds padding or extra landscape scenery on the left and right sides, so the primary screen space still remains taller than it is wide.

Ideally, your application should handle all orientation changes instead of locking into one orientation. When the user rotates the screen, the system restarts the current activity by calling onDestroy() and onCreate()) in immediate succession. You should design your activity to account for these changes in the lifecycle, so the activity can save and restore its state. You can learn about the necessary lifecycle callback methods and how to save and restore the activity state in the Activities document. If your activity state is more complex and cannot retain it using the normal lifecycle callback methods, you can use alternative techniques described in Handling Runtime Changes.

In the worst-case scenario, however, you can avoid orientation changes by using the android:screenOrientation attribute in the <activity> element. Instead of locking the orientation in landscape or portrait, however, you should specify a value of "nosensor". This way, your activity uses whatever orientation the device specifies as its natural orientation and the screen will not rotate. You should still avoid using the android:screenOrientation attribute, but because it's sometimes necessary to lock the screen into one orientation, it's best if you do so in a way that uses the device's natural orientation instead of assuming one specific orientation.

If your application uses the orientation sensors, such as the accelerometer (with the SensorManager APIs), also be aware that the landscape screen can also cause problems, due to false assumptions about which orientation is the natural position. For more information about how you should properly handle rotation changes when using the orientation sensors, read the blog post, One Screen Turn Deserves Another.

Using telephony or other variable features

Tablets and similar devices might not include support for telephony, so they can't make traditional phone calls or handle SMS. Some devices might also omit other hardware features, such as Bluetooth. If your application uses these features, then your manifest file probably already includes (or should include) a declaration of the feature with the <uses-feature> element. Doing so prevents devices that do not declare support for the feature from downloading your applications. For example:

<uses-feature android:name="android.hardware.telephony" />

By default, this declares that your application requires telephony features. So, external services such as Google Play use this information to filter your application from devices that do not offer telephony.

If, however, your application uses, but does not require the feature, you should add to this element, android:required="false". For example:

<uses-feature android:name="android.hardware.telephony" android:required="false" />

This indicates that your application uses the feature, but is still functional if the feature is not available. So, it should still be available to devices that don't provide telephony hardware (or telephony features), such as tablets.

Then in your application code, you must gracefully disable the features that use telephony when it's not available. You can check whether the feature is available using PackageManager.hasSystemFeature(). For example:

PackageManager pm = getPackageManager();
boolean hasTelephony = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);

For more information about these issues and how to future-proof your application for different hardware, read the blog post The Five Steps to Future Hardware Happiness.