Android

You are probably aware that our new Nexus One Android phone comes loaded with live wallpapers. I had the chance to work on some of them and I wanted to share with you high-resolution images of Grass and Galaxy. These two wallpapers were prototyped as desktop applications and you can see below what they look like.

I’ll try to see if I can get these two desktop apps released, hopefully with the code. The desktop versions run on Mac OS X, Linux and Windows.

Galaxy
Grass Night
Grass Sunset

Nexus One live wallpapers

Now that Nexus One is available, I can share with you the high resolution versions of several of the wallpapers that ship on the phone. The photos are available in resolutions up to 22 Mpixels. Enjoy!

romainguy - View my 'Nexus One Wallpapers' set on Flickriver

Nexus One wallpapers

I will be at Devoxx from November the 16th to the 20th to talk about Android. My session will explain how to write resolution independent applications. I will also introduce you to a new exciting graphics technology we’ve been working on.

Android at Devoxx 09

Google I/O and JavaOne are finally over and it’s a good thing, because after 5 sessions and 1 keynote, I was getting a bit tired :) The good news for you is that all of the Android sessions we gave at Google I/O are available online. You can watch the entire video recording of each session and download the slides as PDF files. The JavaOne sessions will probably be posted online later this summer.

Enjoy!

Google I/O videos available

Android’s drawables are extremely useful to easily build applications. A Drawable is pluggable drawing container that is usually associated with a View. For instance, a BitmapDrawable is used to display images, a ShapeDrawable to draw shapes and gradients, etc. You can even combine them to create complex renderings.

Drawables allows to easily customize the rendering of the widgets without subclassing them. As a matter of fact, they are so convenient that most of the default Android apps and widgets are built using drawables; there are about 700 drawables used in the core Android framework. Because drawables are used so extensively throughout the system, Android optimizes them when they are loaded from resources. For instance, every time you create a Button, a new drawable is loaded from the framework resources (android.R.drawable.btn_default). This means all buttons across all the apps use a different drawable instance as their background. However, all these drawables share a common state, called the “constant state.” The content of this state varies according to the type of drawable you are using, but it usually contains all the properties that can be defined by a resource. In the case of a button, the constant state contains a bitmap image. This way, all buttons across all applications share the same bitmap, which saves a lot of memory.

The following diagram shows what entities are created when you assign the same image resource as the background of two different views. As you can see, two drawables are created but they both share the same constant state, hence the same bitmap:

This state sharing feature is great to avoid wasting memory but it can cause problems when you try to modify the properties of a drawable. Imagine an application with a list of books. Each book has a star next to its name, totally opaque when the user marks the book as a favorite, and translucent when the book is not a favorite. To achieve this effect, you would probably write the following code in your list adapter’s getView() method:

Book book = ...;
TextView listItem = ...;

listItem.setText(book.getTitle());

Drawable star = context.getResources().getDrawable(R.drawable.star);
if (book.isFavorite()) {
  star.setAlpha(255); // opaque
} else {
  star.setAlpha(70); // translucent
}

Unfortunately, this piece of code yields a rather strange result, all the drawables have the same opacity:

This result is explained by the constant state. Even though we are getting a new drawable instance for each list item, the constant state remains the same and, in the case of BitmapDrawable, the opacity is part of the constant state. Thus, changing the opacity of one drawable instance changes the opacity of all the other instances. Even worse, working around this issue was not easy with Android 1.0 and 1.1.

Android 1.5 offers a very way to solve this issue with a the new mutate() method. When you invoke this method on a drawable, the constant state of the drawable is duplicated to allow you to change any property without affecting other drawables. Note that bitmaps are still shared, even after mutating a drawable. The diagram below shows what happens when you invoke mutate() on a drawable:

Let’s update our previous piece of code to make use of mutate():

Drawable star = context.getResources().getDrawable(R.drawable.star);
if (book.isFavorite()) {
  star.mutate().setAlpha(255); // opaque
} else {
  star. mutate().setAlpha(70); // translucent
}

For convenience, mutate() returns the drawable itself, which allows to chain method calls. It does not however create a new drawable instance. With this new piece of code, our application now behaves correctly:

If you want to learn more cool techniques, come join us at Google I/O. Members of the Android team will be there to give a series of in-depth technical sessions and answer all your questions.

Drawable mutations

The next few weeks will be quite busy for me. I’ll be at Google I/O the last week of May in San Francisco to give a talk on Android entitled Turbo-charge your UI. If you want to learn cool techniques on how to improve the performance of your Android applications, that’s where you want to be! There will be other very interesting Android talks so if you are an Android developer or wish to become one, I can only encourage you to attend. To make things even better, the registration is actually pretty cheap.

The week following Google I/O, I will be at CommunityOne West, still in San Francisco, to talk about Android again. Actually, this will be (almost) the same talk as Google I/O. CommunityOne is always fun and it’s free.

Finally, I will be at JavaOne to deliver a session (twice) about animations with my good friend Chet Haase. This talk will be language-agnostic, but there will be demos, and the techniques we’ll discuss apply to Swing/Java 2D, Flex, Android, Java FX and any other UI toolkit. I don’t think we’re gonna give away Flex books this year but you’ll be able to laugh at Chet. I mean, laugh at his jokes.

Upcoming conference talks

Android 1.5 is finally available! You can get the brand new SDK as well as a new system image for the Android Developer Phone 1.

Cupcake

Android 1.5 is available

Sharing and reusing layouts is very easy with Android thanks to the <include /> tag, sometimes even too easy and you might end up with user interfaces that contain a large number of views, some of which are rarely used. Thankfully, Android offers a very special widget called ViewStub, which brings you all the benefits of the <include /> without polluting your user interface with rarely used views.

A ViewStub is a dumb and lightweight view. It has no dimension, it does not draw anything and does not participate in the layout in any way. This means a ViewStub is very cheap to inflate and very cheap to keep in a view hierarchy. A ViewStub can be best described as a lazy include. The layout referenced by a ViewStub is inflated and added to the user interface only when you decide so.

The following screenshot comes from the Shelves application. The main purpose of the activity shown in the screenshot is to present the user with a browsable list of books:

Shelves showing a list of books

The same activity is also used when the user adds or imports new books. During such an operation, Shelves shows extra bits of user interface. The screenshot below shows the progress bar and cancel button that appear at the bottom of the screen during an import:

Shelves importing new books

Because importing books is not a common operation, at least when compared to browsing the list of books, the import panel is originally represented by a ViewStub:

The view hierarchy of Shelves before import

When the user initiates the import process, the ViewStub is inflated and replaced by the content of the layout file it references:

The view hierarchy of Shelves during import

To use a ViewStub all you need is to specify an android:id attribute, to later inflate the stub, and an android:layout attribute, to reference what layout file to include and inflate. A stub lets you use a third attribute, android:inflatedId, which can be used to override the id of the root of the included file. Finally, the layout parameters specified on the stub will be applied to the roof of the included layout. Here is an example:

<ViewStub
    android:id="@+id/stub_import"
    android:inflatedId="@+id/panel_import"

    android:layout="@layout/progress_overlay"

    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom" />

When you are ready to inflate the stub, simply invoke the inflate() method. You can also simply change the visibility of the stub to VISIBLE or INVISIBLE and the stub will inflate. Note however that the inflate() method has the benefit of returning the root View of the inflate layout:

((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
// or
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();

It is very important to remember that after the stub is inflated, the stub is removed from the view hierarchy. As such, it is unnecessary to keep a long-lived reference, for instance in an class instance field, to a ViewStub.

A ViewStub is a great compromise between ease of programming and efficiency. Instead of inflating views manually and adding them at runtime to your view hierarchy, simply use a ViewStub. It’s cheap and easy. The only drawback of ViewStub is that it currently does not support the <merge /> tag.

Happy coding!

Android Layout Tricks #4: Optimize, Part 2

Some Android applications require to squeeze every bit of performance out of the UI toolkit and there are many ways to do so. In this article, you will discover how to speed up the drawing and the perceived startup time of your activities. Both these techniques rely on a single feature, the window’s background drawable.

The term window background is a bit misleading however. When you setup your user interface by calling setContentView() on an Activity, Android adds your views to the Activity‘s window. The window however does not contain only your views, but a few others created for you. The most important one is, in the current implementation used on the T-Mobile G1, the DecorView, highlighted in the view hierarchy below:

A typical Android view hierarchy

The DecorView is the view that actually holds the window’s background drawable. Calling getWindow().setBackgroundDrawable() from your Activity changes the background of the window by changing the DecorView‘s background drawable. As mentioned before, this setup is very specific to the current implementation of Android and can change in a future version or even on another device.

If you are using the standard Android themes, a default background drawable is set on your activities. The standard theme currently used on the T-Mobile G1 uses for instance a ColorDrawable. For most applications, this background drawable works just fine and can be left alone. It can however impacts your application’s drawing performance. Let’s take the example of an application that always draws a full screen opaque picture:

An opaque user interface doesn't need a window background

You can see on this screenshot that the window’s background is invisible, entirely covered by an ImageView. This application is setup to redraw as fast as it can and draws at about 44 frames per second, or 22 milliseconds per frame (note: the number of frames per second used in this article were obtained on a T-Mobile G1 with my finger on the screen so as to reduce the drawing speed which would otherwise be capped at 60 fps.) An easy way to make such an application draw faster is to remove the background drawable. Since the user interface is entirely opaque, drawing the background is simply wasteful. Removing the background improves the performance quite nicely:

Remove the background for faster drawing

In this new version of the application, the drawing speed went up to 51 frames per second, or 19 milliseconds per frame. The difference of 3 milliseconds per is easily explained by the speed of the memory bus on the T-Mobile G1: it is exactly the time it takes to move the equivalent of a screenful of pixels on the bus. The difference could be even greater if the default background was using a more expensive drawable.

Removing the window’s background can be achieved very easily by using a custom theme. To do so, first create a file called res/values/theme.xml containing the following:

<resources>
    <style name="Theme.NoBackground" parent="android:Theme">
        <item name="android:windowBackground">@null</item>
    </style>
</resources>

You then need to apply the theme to your activity by adding the attribute android:theme="@style/Theme.NoBackground" to your <activity /> or <application /> tag. This trick comes in very handy for any app that uses a MapView, a WebView or any other full screen opaque view.

Opaque views and Android: this optimization is currently necessary because the Android UI toolkit is not smart enough to prevent the drawing of views hidden by opaque children. The main reason why this optimization was not implemented is simply because there are usually very few opaque views in Android applications. This is however something that I definitely plan on implementing as soon as possible and I can only apologize for not having been able to do this earlier.

Using a theme to change the window’s background is also a fantastic way to improve the perceived startup performance of some of your activities. This particular trick can only be applied to activities that use a custom background, like a texture or a logo. The Shelves application is a good example:

Textured backgrounds are good candidates for window's background

If this application simply set the wooden background in the XML layout or in onCreate() the user would see the application startup with the default theme and its dark background. The wooden texture would only appear after the inflation of the content view and the first layout/drawing pass. This causes a jarring effect and gives the user the impression that the application takes time to load (which can actually be the case.) Instead, the application defines the wooden background in a theme, picked up by the system as soon as the application starts. The user never sees the default theme and gets the impression that the application is up and running right away. To limit the memory and disk usage, the background is a tiled texture defined in res/drawable/background_shelf.xml:

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/shelf_panel"
    android:tileMode="repeat" />

This drawable is simply referenced by the theme:

<resources>
    <style name="Theme.Shelves" parent="android:Theme">
        <item name="android:windowBackground">@drawable/background_shelf</item>
        <item name="android:windowNoTitle">true</item>
    </style>
</resources>

The same exact trick is used in the Google Maps application that ships with the T-Mobile G1. When the application is launched, the user immediately sees the loading tiles of MapView. This is only a trick, the theme is simply using a tiled background that looks exactly like the loading tiles of MapView.

Sometimes the best tricks are also the simplest so the next time you create an activity with an opaque UI or a custom background, remember to change the window’s background.

Download the source code of the first example.

Download the source code of Shelves.

Speed up your Android UI

In the previous installment of Android Layout Tricks, I showed you how to use the <include /> tag in XML layout to reuse and share your layout code. I also mentioned the <merge /> and it’s now time to learn how to use it.

The <merge /> was created for the purpose of optimizing Android layouts by reducing the number of levels in view trees. It’s easier to understand the problem this tag solves by looking at an example. The following XML layout declares a layout that shows an image with its title on top of it. The structure is fairly simple; a FrameLayout is used to stack a TextView on top of an ImageView:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <ImageView  
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
    
        android:scaleType="center"
        android:src="@drawable/golden_gate" />
    
    <TextView
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_marginBottom="20dip"
        android:layout_gravity="center_horizontal|bottom"

        android:padding="12dip"
        
        android:background="#AA000000"
        android:textColor="#ffffffff"
        
        android:text="Golden Gate" />

</FrameLayout>

This layout renders nicely as we expected and nothing seems wrong with this layout:

A FrameLayout is used to overlay a title on top of an image

Things get more interesting when you inspect the result with HierarchyViewer. If you look closely at the resulting tree you will notice that the FrameLayout defined in our XML file (highlighted in blue below) is the sole child of another FrameLayout:

A layout with only one child of same dimensions can be removed

Since our FrameLayout has the same dimension as its parent, by the virtue of using the fill_parent constraints, and does not define any background, extra padding or a gravity, it is totally useless. We only made the UI more complex for no good reason. But how could we get rid of this FrameLayout? After all, XML documents require a root tag and tags in XML layouts always represent view instances.

That’s where the <merge /> tag comes in handy. When the LayoutInflater encounters this tag, it skips it and adds the <merge /> children to the <merge /> parent. Confused? Let’s rewrite our previous XML layout by replacing the FrameLayout with <merge />:

<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <ImageView  
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
    
        android:scaleType="center"
        android:src="@drawable/golden_gate" />
    
    <TextView
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_marginBottom="20dip"
        android:layout_gravity="center_horizontal|bottom"

        android:padding="12dip"
        
        android:background="#AA000000"
        android:textColor="#ffffffff"
        
        android:text="Golden Gate" />

</merge>

With this new version, both the TextView and the ImageView will be added directly to the top-level FrameLayout. The result will be visually the same but the view hierarchy is simpler:

Optimized view hierarchy using the merge tag

Obviously, using <merge /> works in this case because the parent of an activity’s content view is always a FrameLayout. You could not apply this trick if your layout was using a LinearLayout as its root tag for instance. The <merge /> can be useful in other situations though. For instance, it works perfectly when combined with the <include /> tag. You can also use <merge /> when you create a custom composite view. Let’s see how we can use this tag to create a new view called OkCancelBar which simply shows two buttons with customizable labels. You can also download the complete source code of this example. Here is the XML used to display this custom view on top of an image:

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:okCancelBar="http://schemas.android.com/apk/res/com.example.android.merge">

    <ImageView  
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
    
        android:scaleType="center"
        android:src="@drawable/golden_gate" />
    
    <com.example.android.merge.OkCancelBar
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:layout_gravity="bottom"

        android:paddingTop="8dip"
        android:gravity="center_horizontal"
        
        android:background="#AA000000"
        
        okCancelBar:okLabel="Save"
        okCancelBar:cancelLabel="Don't save" />

</merge>

This new layout produces the following result on a device:

Creating a custom view with the merge tag

The source code of OkCancelBar is very simple because the two buttons are defined in an external XML file, loaded using a LayoutInflate. As you can see in the following snippet, the XML layout R.layout.okcancelbar is inflated with the OkCancelBar as the parent:

public class OkCancelBar extends LinearLayout {
    public OkCancelBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOrientation(HORIZONTAL);
        setGravity(Gravity.CENTER);
        setWeightSum(1.0f);
        
        LayoutInflater.from(context).inflate(R.layout.okcancelbar, this, true);
        
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OkCancelBar, 0, 0);
        
        String text = array.getString(R.styleable.OkCancelBar_okLabel);
        if (text == null) text = "Ok";
        ((Button) findViewById(R.id.okcancelbar_ok)).setText(text);
        
        text = array.getString(R.styleable.OkCancelBar_cancelLabel);
        if (text == null) text = "Cancel";
        ((Button) findViewById(R.id.okcancelbar_cancel)).setText(text);
        
        array.recycle();
    }
}

The two buttons are defined in the following XML layout. As you can see, we use the <merge /> tag to add the two buttons directly to the OkCancelBar. Each button is included from the same external XML layout file to make them easier to maintain; we simply override their id:

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <include
        layout="@layout/okcancelbar_button"
        android:id="@+id/okcancelbar_ok" />
        
    <include
        layout="@layout/okcancelbar_button"
        android:id="@+id/okcancelbar_cancel" />
</merge>

We have created a flexible and easy to maintain custom view that generates an efficient view hierarchy:

The resulting hierarchy is simple and efficient

The <merge /> tag is extremely useful and can do wonders in your code. However, it suffers from a couple of limitation:

  • <merge /> can only be used as the root tag of an XML layout
  • When inflating a layout starting with a <merge />, you must specify a parent ViewGroup and you must set attachToRoot to true (see the documentation of the inflate() method)

In the next installment of Android Layout Tricks you will learn about ViewStub, a powerful variation of <include /> that can help you further optimize your layouts without sacrificing features.

Download the complete source code of this example.

Android Layout Tricks #3: Optimize, Part 1

Android comes with a wide variety of widgets, small visual construction blocks you can glue together to present the users with complex and useful interfaces. However applications often need higher level visual components. A component can be seen as a complex widget made of several simple stock widgets. You could for instance reuse a panel containing a progress bar and a cancel button, a panel containing two buttons (positive and negative actions), a panel with an icon, a title and a description, etc. Creating new components can be done easily by writing a custom View but it can be done even more easily using only XML.

In Android XML layout files, each tag is mapped to an actual class instance (the class is always a subclass of View.) The UI toolkit lets you also use three special tags that are not mapped to a View instance: <requestFocus />, <merge /> and <include />. The latter, <include />, can be used to create pure XML visual components. (Note: I will present the <merge /> tag in the next installment of Android Layout Tricks.)

The <include /> does exactly what its name suggests; it includes another XML layout. Using this tag is straightforward as shown in the following example, taken straight from the source code of the Home application that currently ships with Android:

<com.android.launcher.Workspace
    android:id="@+id/workspace"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"

    launcher:defaultScreen="1">

    <include android:id="@+id/cell1" layout="@layout/workspace_screen" />
    <include android:id="@+id/cell2" layout="@layout/workspace_screen" />
    <include android:id="@+id/cell3" layout="@layout/workspace_screen" />

</com.android.launcher.Workspace>

In the <include /> only the layout attribute is required. This attribute, without the android namespace prefix, is a reference to the layout file you wish to include. In this example, the same layout is included three times in a row. This tag also lets you override a few attributes of the included layout. The above example shows that you can use android:id to specify the id of the root view of the included layout; it will also override the id of the included layout if one is defined. Similarly, you can override all the layout parameters. This means that any android:layout_* attribute can be used with the <include /> tag. Here is an example:

<include android:layout_width="fill_parent" layout="@layout/image_holder" />
<include android:layout_width="256dip" layout="@layout/image_holder" />

This tag is particularly useful when you need to customize only part of your UI depending on the device’s configuration. For instance, the main layout of your activity can be placed in the layout/ directory and can include another layout which exists in two flavors, in layout-land/ and layout-port/. This allows you to share most of the UI in portrait and landscape.

Like I mentioned earlier, the next installment will explain the <merge />, which can be particularly powerful when combined with <include />.

Android Layout Trick #2: Include to Reuse

The Android UI toolkit offers several layout managers that are rather easy to use and, most of the time, you only need the basic features of these layout managers to implement a user interface. Sticking to the basic features is unfortunately not the most efficient way to create user interfaces. A common example is the abuse of LinearLayout, which leads to a proliferation of views in the view hierarchy. Every view, or worse every layout manager, you add to your application comes at a cost: initialization, layout and drawing become slower. The layout pass can be especially expensive when you nest several LinearLayout that use the weight parameter, which requires the child to be measured twice.

Let’s consider a very simple and common example of a layout: a list item with an icon on the left, a title at the top and an optional description underneath the title. Here is what such an item looks like:

Simple list item

To clearly understand how the views, one ImageView and two TexView, are positioned with respect to each other, here is the wireframe of the layout as captured by HierarchyViewer:

Wireframe of the simple list item

Implementing this layout is straightforward with LinearLayout. The item itself is a horizontal LinearLayout with an ImageView and a vertical LinearLayout, which contains the two TextViews. The source code of this layout is the following:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    
    android:padding="6dip">
    
    <ImageView
        android:id="@+id/icon"
        
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_marginRight="6dip"
        
        android:src="@drawable/icon" />

    <LinearLayout
        android:orientation="vertical"
    
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="fill_parent">

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
                    
            android:gravity="center_vertical"
            android:text="My Application" />
            
        <TextView  
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1" 
            
            android:singleLine="true"
            android:ellipsize="marquee"
            android:text="Simple application that shows how to use RelativeLayout" />
            
    </LinearLayout>

</LinearLayout>

This layout works but can be wasteful if you instantiate it for every list item of a ListView. The same layout can be rewritten using a single RelativeLayout, thus saving one view, and even better one level in view hierarchy, per list item. The implementation of the layout with a RelativeLayout remains simple:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    
    android:padding="6dip">
    
    <ImageView
        android:id="@+id/icon"
        
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:layout_marginRight="6dip"
        
        android:src="@drawable/icon" />

    <TextView  
        android:id="@+id/secondLine"

        android:layout_width="fill_parent"
        android:layout_height="26dip" 
        
        android:layout_toRightOf="@id/icon"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        
        android:singleLine="true"
        android:ellipsize="marquee"
        android:text="Simple application that shows how to use RelativeLayout" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        
        android:layout_toRightOf="@id/icon"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_above="@id/secondLine"
        android:layout_alignWithParentIfMissing="true"
                
        android:gravity="center_vertical"
        android:text="My Application" />

</RelativeLayout>

This new implementation behaves exactly the same way as the previous implementation, except in one case. The list item we want to display has two lines of text: the title and an optional description. When a description is not available for a given list item, the application would simply set the visibility of the second TextView to GONE. This works perfectly with the LinearLayout implementation but not with the RelativeLayout version:

RelativeLayout and description GONE
RelativeLayout and description GONE

In a RelativeLayout, views are aligned either with their parent, the RelativeLayout itself, or other views. For instance, we declared that the description is aligned with the bottom of the RelativeLayout and that the title is positioned above the description and anchored to the parent’s top. With the description GONE, RelativeLayout doesn’t know where to position the title’s bottom edge. To solve this problem, you can use a very special layout parameter called alignWithParentIfMissing.

This boolean parameter simply tells RelativeLayout to use its own edges as anchors when a constraint target is missing. For instance, if you position a view to the right of a GONE view and set alignWithParentIfMissing to true, RelativeLayout will instead anchor the view to its left edge. In our case, using alignWithParentIfMissing will cause RelativeLayout to align the title’s bottom with its own bottom. The result is the following:

RelativeLayout, description GONE and alignWithParentIfMissing
RelativeLayout, description GONE and alignWithParentIfMissing

The behavior of our layout is now perfect, even when the description is GONE. Even better, the hierarchy is simpler and because we are not using LinearLayout’s weights it’s also more efficient. The difference between the two implementations becomes obvious when comparing the view hierarchies in HierarchyViewer:

LinearLayout vs RelativeLayout

Again, the difference will be much more important when you use such a layout for every item in a ListView for instance. Hopefully this simple example showed you that getting to know your layouts is the best way to learn how to optimize your UI.

Android Layout Tricks #1

Android is a mobile operating system meant to be run on a wide array of devices, with very different hardware configurations. Some devices, like the T-Mobile G1, can change their hardware configuration at runtime. For instance, when you open the keyboard, the screen change from the portrait orientation to the landscape orientation. To make Android applications development easier, the OS automatically handles configuration changes and restart the current activity with the new configuration. This is the default behavior that lets you declare resources like layouts and drawables based on the orientation, screen size, locale, etc. If you are not familiar with the way Android handles resources, I highly suggest you to read the official documentation on resources.

While this behavior is really powerful, since your application adapts automatically to the device’s configuration at runtime, it is sometimes confusing for new Android developers who wonder why their activity is destroyed and recreated. Facing this “issue,” some developers choose to handle configuration changes themselves which is, in my opinion, a short-term solution that will complicate their life when other devices come out or when the application becomes more complex. The automatic resource handling is a very efficient and easy way to adapt your application’s user interface to various devices and devices configurations. It sometimes comes at a price though.

When your application displays a lot of data, or data that is expensive to fetch, the automatic destruction/creation of the activities can be lead to a painful user experience. Take the example of Photostream, a simple Flickr browsing application I wrote for the release of Android 1.0. After you launch the application and choose a Flickr account, the application downloads a set of 6 photos (on a T-Mobile G1) from the Flickr servers and displays them on screen. To improve the user experience, I also use slightly different layouts and drawables in portrait and landscape, and this is what the result looks like:

Photostream in portrait mode
Photostream in landscape mode

Photostream lets Android take care of the configuration change when the screen is rotated. However, can you imagine how painful it would be for the user to see all the images being downloaded again? The obvious solution to this problem is to temporarily cache the images. They could be cached on the SD card (if there’s one), in the Application object, in a static field, etc. None of these techniques is adapted to the current situation: why should we bother caching the images when the screen is not rotated? Fortunately for us, Android offers a great API exactly for that purpose.

The Activity class has a special method called onRetainNonConfigurationInstance(). This method can be used to pass an arbitrary object your future self and Android is smart enough to call this method only when needed. In the case of Photostream, I used this method to pass the downloaded images to the future activity on orientation change. The implementation can be summarized like so:

@Override
public Object onRetainNonConfigurationInstance() {
    final LoadedPhoto[] list = new LoadedPhoto[numberOfPhotos];
    keepPhotos(list);
    return list;
}

In the new activity, in onCreate(), all you have to do to get your object back is to call getLastNonConfigurationInstance(). In Photostream, this method is invoked and if the returned value is not null, the grid is loaded with the list of photos from the previous activity:

private void loadPhotos() {
    final Object data = getLastNonConfigurationInstance();
    
    // The activity is starting for the first time, load the photos from Flickr
    if (data == null) {
        mTask = new GetPhotoListTask().execute(mCurrentPage);
    } else {
        // The activity was destroyed/created automatically, populate the grid
        // of photos with the images loaded by the previous activity
        final LoadedPhoto[] photos = (LoadedPhoto[]) data;
        for (LoadedPhoto photo : photos) {
            addPhoto(photo);
        }
    }
}

Be very careful with the object you pass through onRetainNonConfigurationChange() though. If the object you pass is for some reason tied to the Activity/Context, you will leak all the views and resources of the activity. This means you should never pass a View, a Drawable, an Adapter, etc. Photostream for instance extracts the bitmaps from the drawables and pass the bitmaps only, not the drawables. Finally, remember that onRetainNonConfigurationChange() should be used only to retain data that is expensive to load. Otherwise, keep it simple and let Android do everything.

Faster Screen Orientation Change with Android

Despite the impressive hardware of the first Android phones (T-Mobile G1 and ADP1) writing efficient mobile applications is not always straightforward. Android applications rely on automatic memory management handled by Dalvik’s garbage collector which can sometimes cause performance issues if you are not careful with memory allocations.

In a performance sensitive code path, like the layout or drawing method of a view or the logic code of a game, any allocation comes at a price. After too many allocations, the garbage collector will kick in and stop your application to let it free some memory. Most of the time, garbage collections happen fast enough for you not to notice. However, if a collection happens while you are scrolling through a list of items or while you are trying to defeat a foe in a game, you may suddenly see a drop in performance/responsiveness of the application. It’s not unusual for a garbage collection to take 100 to 200 ms. For comparison, a smooth animation needs to draw each frame in 16 to 33 ms. If the animation is suddenly interrupted for 10 frames, you can be certain that your users will notice.

Most of the time, garbage collection occurs because of tons of small, short-lived objects and some garbage collectors, like generational garbage collectors, can optimize the collection of these objects so that the application does not get interrupted too often. The Android garbage collector is unfortunately not able to perform such optimizations and the creation of short-lived objects in performance critical code paths is thus very costly for your application.

To help you avoid frequent garbage collections, the Android SDK ships with a very useful tool called allocation tracker. This tool is part of DDMS, which you must have already used for debugging purposes. To start using the allocation tracker, you must first launch the standalone version of DDMS, which can be found in the tools/ directory of the SDK. The version of DDMS included in the Eclipse plugin does not offer you ability to use the allocation tracker yet.

Once DDMS is running, simply select your application process and then click the Allocation Tracker tab. In the new view, click Start Tracking and then use your application to make it execute the code paths you want to analyze. When you are ready, click Get Allocations. A list of allocated objects will be shown in the first table. By clicking on a line you can see, in the second table, the stack trace that led to the allocation. Not only you will know what type of object was allocated, but also in which thread, in which class, in which file and at which line. The following screenshot shows the allocations performed by Shelves while scrolling a ListView.

Android's allocation tracker

Even though it is not necessary, or sometimes not possible, to remove all allocations for your performance critical code paths. the allocation tracker will help you identify important issues in your code. For instance, a common mistake I have seen in many applications is to create a new Paint object on every draw. Moving the paint into an instance field is a simple fix that helps performance a lot. I highly encourage you to peruse the Android source code to see how we reduce allocations in performance critical code paths. You will also thus discover the APIs Android provide to help you reuse objects.

Happy allocations hunting!

Track memory allocations on Android

A few months ago, I showed Shelves, an application to manage a collection of books on Android powered phones. I am an avid user of Delicious Library on MacOS X and I since no similar application existed at the time for Android, I decided to write my own. Needless to say, Shelves was largely inspired by Delicious Library.

Even though Shelves is not quite ready to be release on the Android Market, I decided to publish the source code under the Apache 2.0 license. The application is already usable and lets you add books by searching Google Books or by scanning their barcode (if you have the application called Barcode Scanner installed), search your collection by keywords or barcodes, import books from a CSV file and delete individual books. The only two features I need to implement before releasing Shelves are the ability to manually add/edit a book and to view a book’s details.

If you are curious, you can see Shelves in action in the following video. You can also visit Shelve’s project page for screenshots showcasing several features.

Note: the colors on the video are different from what you would see on an Android device. I created the assets specifically for mobile devices and the colors appear therefore more saturated on a computer monitor.

Shelves, an Open Source Android application

ListView is one of Android’s most widely used widgets. It is rather easy to user, very flexible and incredibly powerful. ListView can also be difficult to understand at times.

One of the most common issues with ListView happens when you try to use a custom background. By default, like many Android widgets, ListView has a transparent background which means yo can see through the default window’s background, a very dark gray (#FF191919 with the current dark theme.) Additionally, ListView enables the fading edges by default, as you can see at the top of the following screenshot; the first text item gradually fades to black. This technique is used throughout the system to indicate that the container can be scrolled.

Android's default ListView

The fade effect is implemented using a combination of Canvas.saveLayerAlpha() and the Porter-Duff Destination Out blending mode. This technique is similar to the one explained in Filthy Rich Clients and various presentations. Unfortunately, things start to get ugly when you try to use a custom background on the ListView or when you change the window’s background. The following two screenshots show what happens in an application when you change the window’s background. The left image shows what the list looks like by default and the right image shows what the list looks like during a scroll initiated with a touch gesture:

Dark fadeDark list

This rendering issue is caused by an optimization of the Android framework enabled by default on all instances of ListView (for some reason, I forgot to enable it by default on GridView.) I mentioned earlier that the fade effect is implemented using a Porter-Duff blending mode. This implementation works really well but is unfortunately very costly and can bring down drawing performance by quite a bit as it requires to capture a portion of the rendering in an offscreen bitmap and then requires extra blending (which implies readbacks from memory.)

Since ListView is most of the time displayed on a solid background, there is no reason to go down that expensive route. That’s why we introduced an optimization called the “cache color hint.” The cache color hint is an RGB color set by default to the window’s background color, that is #191919 in Android’s dark theme. When this hint is set, ListView (actually, its base class View) knows it will draw on a solid background and therefore replaces th expensive saveLayerAlpha()/Porter-Duff rendering with a simple gradient. This gradient goes from fully transparent to the cache color hint value and this is exactly what you see on the image above, with the dark gradient at the bottom of the list. However, this still does not explain why the entire list turns black during a scroll.

As I said before, ListView has a transparent/translucent background by default, and so all default Android widgets. This implies that when ListView redraws its children, it has to blend the children with the window’s background. Once again, this requires costly readbacks from memory that are particularly painful during a scroll or a fling when drawing happens dozen of times per second. To improve drawing performance during scrolling operations, the Android framework reuses the cache color hint. When this hint is set, the framework copies each child of the list in a Bitmap filled with the hint value (this assumes that another optimization, called scrolling cache, is not turned off.) ListView then blits these bitmaps directly on screen and because these bitmaps are known to be opaque, no blending is required. And since the default cache color hint is #191919, you get a dark background behind each item during a scroll.

To fix this issue, all you have to do is either disable the cache color hint optimization, if you use a non-solid color background, or set the hint to the appropriate solid color value. This can be dome from code or preferably from XML, by using the android:cacheColorHint attribute. To disable the optimization, simply use the transparent color #00000000. The following screenshot shows a list with android:cacheColorHint="#00000000" set in the XML layout file:

Fade on a custom background

As you can see, the fade works perfectly against the custom wooden background. I find the cache color hint feature interesting because it shows how optimizations can make developers’ life more difficult in some situations. In this particular case, however, the benefit of the default behavior outweighs the added complexity for the developer.

Why is my list black? An Android optimization

Android applications are, at least on the T-Mobile G1, limited to 16 MB of heap. It’s both a lot of memory for a phone and yet very little for what some developers want to achieve. Even if you do not plan on using all of this memory, you should use as little as possible to let other applications run without getting them killed. The more applications Android can keep in memory, the faster it will be for the user to switch between his apps. As part of my job, I ran into memory leaks issues in Android applications and they are most of the time due to the same mistake: keeping a long-lived reference to a Context.

On Android, a Context is used for many operations but mostly to load and access resources. This is why all the widgets receive a Context parameter in their constructor. In a regular Android application, you usually have two kinds of Context, Activity and Application. It’s usually the first one that the developer passes to classes and methods that need a Context:

@Override
protected void onCreate(Bundle state) {
  super.onCreate(state);
  
  TextView label = new TextView(this);
  label.setText("Leaks are bad");
  
  setContentView(label);
}

This means that views have a reference to the entire activity and therefore to anything your activity is holding onto; usually the entire View hierarchy and all its resources. Therefore, if you leak the Context (“leak” meaning you keep a reference to it thus preventing the GC from collecting it), you leak a lot of memory. Leaking an entire activity can be really easy if you’re not careful.

When the screen orientation changes the system will, by default, destroy the current activity and create a new one while preserving its state. In doing so, Android will reload the application’s UI from the resources. Now imagine you wrote an application with a large bitmap that you don’t want to load on every rotation. The easiest way to keep it around and not having to reload it on every rotation is to keep in a static field:

private static Drawable sBackground;

@Override
protected void onCreate(Bundle state) {
  super.onCreate(state);
  
  TextView label = new TextView(this);
  label.setText("Leaks are bad");
  
  if (sBackground == null) {
    sBackground = getDrawable(R.drawable.large_bitmap);
  }
  label.setBackgroundDrawable(sBackground);
  
  setContentView(label);
}

This code is very fast and also very wrong; it leaks the first activity created upon the first screen orientation change. When a Drawable is attached to a view, the view is set as a callback on the drawable. In the code snippet above, this means the drawable has a reference to the TextView which itself has a reference to the activity (the Context) which in turns has references to pretty much anything (depending on your code.)

This example is one of the simplest cases of leaking the Context and you can see how we worked around it in the Home screen’s source code (look for the unbindDrawables() method) by setting the stored drawables’ callbacks to null when the activity is destroyed. Interestingly enough, there are cases where you can create a chain of leaked contexts. I can’t remember an exact case right now, but I have fixed a couple of those, and they are bad. They make you run out of memory rather quickly.

There are two easy ways to avoid context-related memory leaks. The most obvious one is to avoid escaping the context outside of its own scope. The example above showed the case of a static reference but inner classes and their implicit reference to the outer class can be equally dangerous. The second solution is to use the Application context. This context will live as long as your application is alive and does not depend on the activities life cycle. If you plan on keeping long-lived objects that need a context, remember the application object. You can obtain it easily by calling Context.getApplicationContext() or Activity.getApplication().

In summary, to avoid context-related memory leaks, remember the following:

  • Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)
  • Try using the context-application instead of a context-activity
  • Avoid non-static inner classes in an activity if you don’t control their life cycle, use a static inner class and make a weak reference to the activity inside

And remember that a garbage collector is not an insurance against memory leaks. Last but not least, we try to make such leaks harder to make happen whenever we can.

Avoid memory leaks on Android

Android offers a very powerful and yet easy to use tool called intents. An intent can be use to turn applications into high-level libraries and make code re-use something even better than before. The Android Home screen and AnyCut use intents extensively to create shortcuts for instance. While it is nice to be able to make use of a loosely coupled API, there is no guarantee that the intent you send will be received by another application. This happens in particular with 3rd party apps, like Panoramio and its RADAR intent.

While working on a new application, I came up with a very simple way to find out whether the system contains any application capable of responding to the intent you want to use. I implemented this technique in my application to gray out the menu item that the user would normally click to trigger the intent. The code is pretty simple and easy to follow:

/**
 * Indicates whether the specified action can be used as an intent. This
 * method queries the package manager for installed packages that can
 * respond to an intent with the specified action. If no suitable package is
 * found, this method returns false.
 *
 * @param context The application's environment.
 * @param action The Intent action to check for availability.
 *
 * @return True if an Intent with the specified action can be sent and
 *         responded to, false otherwise.
 */
public static boolean isIntentAvailable(Context context, String action) {
    final PackageManager packageManager = context.getPackageManager();
    final Intent intent = new Intent(action);
    List list =
            packageManager.queryIntentActivities(intent,
                    PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

Here is how I use it:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    final boolean scanAvailable = isIntentAvailable(this,
        "com.google.zxing.client.android.SCAN");

    MenuItem item;
    item = menu.findItem(R.id.menu_item_add);
    item.setEnabled(scanAvailable);

    return super.onPrepareOptionsMenu(menu);
}

In this example, the menu is grayed out if the Barcode Scanner application is not installed. Another, simpler, way to do this is to catch the ActivityNotFoundException when calling startActivity() but it only lets you react to the problem, you cannot predict it and update the UI accordingly to prevent the user from doing something that won’t work. The technique described here can also be used at startup time to ask the user whether he’d like to install the missing package, you can then simply redirect him to the Android Market by using the appropriate URI.

Android: Can I use this Intent?

Devoxx is unfortunately over but it was, as usual, awesome! Congratulations once again to the Devoxx team for their hard work and a fantastic result. I am really glad where the conference is going as this year it wasn’t only about Java. We thus got sessions on Flex, Silverlight, Groovy, Android… I can’t wait to go back next year to discover what else we’re gonna see.

Although I didn’t attend many sessions this week I really enjoyed what I saw about Flex. The ease with which you can apply animations, transitions and other various effects to live widgets is, not surprisingly, very appealing to me. Chet most notably showed how to apply PixelBender shaders to widgets and I can’t wait to give this a try. Benjamin also demonstrated his amazing Parleys Publisher tool, a video editing tool written in Flex/AIR. This tool can analyze a video stream and detect where the speaker changes slides to automatically create chapters. I would love to see the source code of that app.

I also enjoyed the session about Parleys.com, where Stephan presented various implementations of the Parleys.com player in Flex, GWT, JavaFX and iPhone. I was surprised and impressed by the visual quality of the GWT app, which was very close to the JavaFX version (the Flex implementation is one version ahead and richer, both in terms of visuals and features.) You can go try the current parleys player on parleys.com.

If you never went to Devoxx (well, JavaPolis), you really should try to go next year. It is a great event where you can meet very interesting people and enjoy Belgium beer.

Devoxx 08 Wrapup

As of today, developers can buy an Android development phone. What is so great about it? It is not SIM-locked and you can flash the firmware with the Open Source Android code base. These developments phones are basically what the Android team uses every day. They’re even better because they are based on the final production design.

Android Development Phone

Go get your your Dev Phone 1, write applications, write patches for the platform and come join the fun!

Also, I’ll be presenting two sessions on Android next week at Devoxx :)

Official Android Development Phones

I’ve been using IntelliJ IDEA 8 since its recent release and I love it. There are not many new features I will use but the UI and performance improvements are most welcome. Congratulations to the JetBrains team for another excellent release!

IntelliJ IDEA 8

Today was a very exciting day for me and all the members of the Android team. Not only did we released the source code (more than 11 million lines of code) but T-Mobile also launched the first device, the G1, in select stores. Click the picture below for some photos to the launch event in San Francisco. This is very very exciting to finally see an Android product in the hands of actual users; it’s a weird and rewarding feeling after all the hard work we accomplished.

Boxed Logo

Android Source Code and Launch

I am very happy to say that I will be at Devoxx this year to give a couple of presentations about Android. The presentations are, very surprisingly, entitled Filthy Rich Android Clients. If you want to learn cool stuff about Android and/or if you want to see cool demos running on a real Android phone, come to Devoxx :)

Android talk at Devoxx

A new cool application was released by Google this week as part of the Apps for Android project. This application is called Photostream and lets you browse the photos collection of any Flickr user. The official Android blog has more details about the application.

Browsing through photosViewing a photo

The source code is available on the Subversion repository and is licensed under the Apache 2.0 License. The repository contains the source code of equally cool applications like Globaltime (the Earth in 3D), Translate or WikiNotes.

If you want to know what it looks like without downloading and installing it yourself, you can take a look at a video of the application in action. The video shows the application running on the emulator from the recent Android SDK 0.9.

Another cool Android application