Mobile for the masses: Activities and icons in your Android application lifecycle

Add navigation with style to your Android mobile apps

The Activity class is the workhorse of an Android mobile app, and it's also where you can fine-tune your app's interactions with both the user and the mobile device. Get things working exactly the way you want them in your app's lifecycle, then use icons and action bars to guide users through UI navigation and other app features.

Andrew Glover, CTO, App47

Andrew GloverAndrew Glover is a developer and mobile technology enthusiast. He's currently the CTO of App47 and is the founder of the easyb behavior-driven development (BDD) framework. He is also the co-author of three books: Continuous Integration, Groovy in Action, and Java Testing Patterns. You can keep up with Andrew by reading his blog and by following him on Twitter.



28 May 2013

Also available in Chinese Russian Japanese Vietnamese Portuguese

Introduction

About this series

Mobile application distribution is exploding, and so is the market for mobile development skills. This developerWorks series introduces the mobile landscape to developers who are experienced with programming but new to mobility.

Start out coding native apps in Java™ code, then expand your toolkit to include JVM languages, scripting frameworks, HTML5/CSS/JavaScript, third-party tools, and more. Step by step, you'll master the skills you need to meet virtually any mobile development scenario.

Mobile devices today are incredibly powerful, much more so than the desktop computers that many developers used to write our first programs. So it's easy to forget that a mobile device is still a resource-constrained environment. When you develop a mobile application, you should never forget the limitations of the environment it runs in. This is especially true when you consider that your application will be competing for system resources with other apps — some of them more crucial to a user's day-to-day activities than yours.

One way to make sure that your app is widely used is to ensure that it conserves system resources. In Android, a mechanism for both using and conserving system resources is the Activity class. The better you understand the lifecycle of this fancy workhorse (which is very similar to a Java Servlet), the better you'll be able to fine-tune your Android mobile application's resource usage and performance.

We'll start with a quick dive into the Activity class lifecycle. You'll learn about the methods that handle each stage of an Android app's lifecycle by playing with them in a demo app. Once you understand how these methods work together, you'll be in good shape to use system resources wisely. Then you'll switch gears and update your demo app's navigation system to use action icons rather than menu buttons for user interaction. Icons are pretty standard in mobile app UIs, and newer Android devices (version 4.2.2 and higher) have deprecated the option menu in favor of an action bar. Knowing how to integrate these features with your Android mobile apps will serve you well!


The Activity class lifecycle

The lifecycle of an Activity maps directly to the lifecycle of an Android mobile application. As a user interacts with either your app or the device that hosts it, the Android platform executes callbacks on an Activity instance. When a user starts up your app, an initial Activity executes a defined lifecycle; it executes a different stage of the lifecycle when the app is backgrounded, and yet another one when it is shut down. Figure 1 shows the Android Activity lifecycle at each stage of interaction.

Figure 1. Android's Activity lifecycle
A diagram of an Android mobile app's Activity lifecycle.

The Android mobile app lifecycle consists of four stages:

  • Start
  • Pause and resume
  • Stop and restart
  • Destroy

Learn about each stage and its callback methods (which you can implement inside an Activity instance) in the sections that follow.

Start in the Activity lifecycle

The demo app

If you've been following along with this series, then you've already created your own demo app in the first and second articles in this series. If you don't have a demo app, I recommend that you create one before continuing. Alternatively, you could clone the Git repository for my own Overheard Word demo app (see Resources).

In previous articles, you've used the callback method that corresponds to starting an Activity, which is onCreate. You might also be familiar with onStart and onResume, two additional methods that are invoked upon starting. Now consider these methods in context of the Activity lifecycle.

In your Eclipse Android development environment, you can easily override methods by selecting the Override/Implement Methods... option, as shown in Figure 2.

Figure 2. Overriding Activity lifecycle callback methods
A screenshot of overriding actvity lifecycle callback methods in Eclipse.

Next, select both the onStart and onResume methods:

Figure 3. Picking a callback
A screenshot of picking a callback in Eclipse.

Now use Android's Log class to put in some trace statements, like I've done in Listing 1.

Listing 1. Implementing Android Activity callbacks
@Override
protected void onResume() {
    super.onResume();
    Log.d("overheardword", "onResume Invoked");
}

@Override
protected void onStart() {
    super.onStart();
    Log.d("overheardword", "onStart Invoked");
}

You can check the results by firing up an instance of your app and watching the logs via LogCat, as shown in Figure 4.

Figure 4. LogCat's debug statements
A screenshot of Logcat's debug statements.

Android logging with LogCat

Android comes with its own logging system, android.util.Log. With this handy class, you can log at various levels (such as info, warn, debug, etc.) and see the logs via the logcat tool that ships with your Android SDK. In Eclipse, you should see LogCat as a tab, which you can use to filter tags and even app instances. LogCat also lets you access logs on a device by simply plugging the device into your desktop or laptop's USB outlet.

As you've probably guessed, onCreate is called the first time your app is loaded, while onStart and onResume are handy in the context of other stages, such as when an app is backgrounded and restarted.

Pause and resume in the Activity lifecycle

Because mobile devices typically host many apps, which compete in various ways for a user's attention, it is important that your app knows when to let another application occupy the device's screen and consume more of its resources. Sometimes a user will need to take an incoming call while using your app, or your app might issue a pop-up dialog such as a request for information or an error message. Either action will partly obstruct the current Activity.

When an Activity is partially obstructed, the onPause method is called. When the paused Activity regains focus, onResume is invoked. A pause-and-resume means that the affected activity was partially obstructed but not completely hidden.

When the app is completely hidden, for example, when a user takes a phone call, onPause is also invoked, but in this case it is followed by onStop. When the app is foregrounded again, onRestart is invoked, followed by onStart, and then by onResume.

Let's see what happens when you implement onPause, onRestart, and onStop. If you've got an Android application you're already working with for this series, add some log statements to your code and then fire it up. Tap the Home button to completely hide the instance, and then tap its icon to fire it back up. You should see a series of methods being invoked. First, you'll see onPause followed by onStop. When you click the icon to re-fire the app, you'll see onRestart followed by onStart, and then by onResume.

Destroying an Activity is something that also occurs in the normal process of running an app. For instance, you can signify the termination of an Activity instance by calling its finish method. What's key here is that because an Activity is being shut down, it will follow the same lifecycle as if it were being hidden, but its final callback will be onDestroy.

In Listing 2, I use my own Overheard Word app (see "Mobile for the masses: Take a swipe at it!" or get the source from Github) to demonstrate this process, by invoking the finish method on an upward-swipe motion.

Listing 2. Destroying an Activity instance
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
   try {
       final SwipeDetector detector = new SwipeDetector(e1, e2, velocityX, velocityY);
       if (detector.isDownSwipe()) {
        return false;
       }else if (detector.isUpSwipe()) {
        finish();
       }else if (detector.isLeftSwipe()) {
        Toast.makeText(getApplicationContext(), "Left Swipe", Toast.LENGTH_SHORT).show();
       }else if (detector.isRightSwipe()) {
        Toast.makeText(getApplicationContext(), "Right Swipe", Toast.LENGTH_SHORT).show();
       }
   } catch (Exception e) {
       // nothing
   }
   return false;
}

The Activity lifecycle methods you are most likely to use are onCreate, onRestart, and onDestroy. For instance, I've used onRestart to refresh an aspect of many an app's UI view and onDestroy to release connections to a database such as SQLite, which runs locally on Android devices.

It might not be apparent just yet, but once you start working with outside resources — such as external web services or a device's file system or database — these lifecycle stages will become extremely important.

Next let's see what happens when we use two Activity hook methods —onCreateOptionsMenu and onOptionsItemSelected— to implement app menu behavior. Once we get those two methods synchronized, we'll connect their functionality to icons for extra UI pizazz.


Navigation with menus and actions

When I created the Overheard Word project in Eclipse, the first Activity I defined had a stub method called onCreateOptionsMenu. As you might guess, this method creates an options menu. On older Android devices, the options menu is represented by the Menu button. On newer devices, it is represented as a series of vertical dots, which are displayed in the app itself. Newer Android devices are not required to have a menu button.

In an emulator instance representing an older device, you will see a button labeled "Menu." On clicking it, an app instance will display a menu of options. In this case, we'll look at options for navigation. If a user pressed the Home button, for instance, he or she would see something like what's shown in Figure 5.

Figure 5. An un-implemented menu item
A screenshot of an unimplemented menu item displaying in the Android emulator.

On a tablet, there is no menu button. Rather than selecting items from a menu, users are asked to initiate various actions. This newer UI aspect, known as an action bar, is shown in Figure 6.

Figure 6. Android's new action bar
Android's new action bar in the Android emulator.

While a menu button and an action bar behave similarly, the action bar is implemented only on newer devices. Since we're targeting an older version of Android (remember that roughly 50 percent of all Android devices run Gingerbread!), I'll use the more familiar menu button for demonstration purposes. Later I'll show you how to update your navigational code to implement an action bar, should you want to target newer versions of Android and corresponding devices.

Create an options menu

A good first step toward retrofitting Overheard Word for more efficient user interaction is to implement an options menu that enables a user to quit out of the app. Quitting the app is a stage of the Activity lifecycle, so we'll be using Activity methods to implement this functionality.

Remember that all UI-related business in an Android app corresponds to an XML file, so editing a layout XML file is how you define a UI. An Android app's XML files live in specific directories within the res folder of the project (for example, layout files live in the layout directory).

For a quick exercise, take a look at the default implementation of the onCreateOptionsMenu method in Overheard Word's main activity — what does this code tell you?

public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.overheard_word, menu);
  return true;
 }

If you're thinking about looking for an XML file dubbed overheard_word.xml in a resource directory named menu, then you're well on your way to becoming an Android expert!

I... Quit!

Next, let's edit the menu resource XML file to add a menu item called quit. Start by finding the strings.xml file in your res/values directory. Once you're there, create a new entry like this one:

<string name="quit_menu">Quit</string>

This markup defines the word Quit that can be referenced via the identifier quit_menu (this facilitates internationalizing apps quite nicely, by the way). Next, open up the overheard_word.xml file in the menu directory. In that file, change the title to @string/quit_menu, thus linking the word Quit to the menu item.

Now start your emulator and press the Menu button. You should see a menu appear at the bottom of your screen with one option: Quit. Selecting it will do nothing, however, because you haven't implemented it yet.

We'll add implementation code for the Quit option in a minute. But first let's consider another important element of any functional piece of a mobile app, which is its look and feel. You might have noticed that a lot of mobile UIs these days (and even an increasing number of web application UIs) use icons for navigation. Let's see what happens when we replace the generic word button with a free icon.


Icons in mobile UI design

Before I got into mobile development, I dabbled in icons, but rarely used them in my enterprise applications. When web apps started becoming more interactive, I found myself using icons more. It wasn't until I got into mobile development, however, that they really took center stage for me.

Where's my icon?

Today it's easy to find icons that are freely available for use in open source and commercial apps. You can also purchase the rights to use some icons for a small fee. I personally favor a package called Glyphish (see Resources), which has hundreds of icons to choose from and an extremely reasonable licensing fee. Glyphish also offers a free license with attribution. I suggest that you do a quick search and find an icon that you want to use for the demonstration in this section.

If you use icons for Android mobile UI design, you need to be keenly aware of device resolution. Because the Android device ecosystem is so large, your app is likely to run on a wide range of devices, from low-resolution small-screen devices all the way up to high-resolution tablets with 7-inch screens. An icon that displays well on a hand-held device might appear grainy on a tablet.

Fortunately, you can control the look of your app's icons on different devices. Take a quick look in the res directory of your Android mobile app. You should see a few directories labeled drawable-something-pdi (where "something" is a series of letters). These directories correspond to various device-screen resolutions. Placing correctly sized icons and other image files in these directories will ensure that your icons display correctly on different types of devices.

For an ultra-high-resolution device, for instance, Android will look for icons in the drawable-xxhdpi directory. A launcher icon in this directory should be 96 x 96 pixels and at least 320 dpi. A launcher icon in the drawable-ldpi directory should be 36 x 26 pixels and 120 dpi. You also have the option to create a default drawable directory, which Android will use if it can't find a corresponding file for a given icon resolution.

To keep things simple, I will create a drawable directory for my Overheard Word app. In it, I'll place a 26 x 26 icon file (a .png) that I want to use for my quit option.

Figure 7. Adding an icon to a drawable directory
A screenshot of the drawable directory in Eclipse.

My next step is to reference that icon in my options menu, which I do by updating the menu item in my overheard_word.xml file like so:

android:icon="@drawable/quit_icon"

If you're following along with me, you should also update the id of the same element. Give it a descriptive string value like this one:

android:id="@+id/quit_item"

Having a descriptive, easily understood string value will be helpful when it comes to our next step, which is implementing the quitting behavior inside the onOptionsItemSelected method. We'll be able to reference the menu item in the event of a selection, via the ID of quit_item. For now, fire up your emulator and press the Menu button. I think you'll like what you see!

Figure 8. Nice icon! (Courtesy of Glyphish)
A screenshot of Overheard Word's new Quit icon in the Android emulator.

Implementing menu behavior

Now I have a great-looking icon for my Quit menu item (and I hope you have a corresponding one for your own app), but I still need to add the code that tells my app what to do when that button is tapped.

Implementing any behavior in the options menu starts with overriding the onOptionsItemSelected method. So override that method, and then update your code to look like mine below (but remember to adjust the menu item ID for your own app):

Listing 3. Handling menu item selection
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.quit_item:
        this.finish();
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

Note that this is just a simple switch statement. If the id of quit_item is selected, the finish method will be invoked, essentially shutting down the app.

Try out this new code in your emulator: touch the Menu button, hit the quit (X) option, and watch what happens on LogCat. You should see a full Activity lifecycle run through its stages: onPause followed by onStop and then by onDestroy.


Action bars in Android 3.x

As I mentioned earlier, newer versions of Android (Honeycomb and later) eschew the option menu in favor of an action bar. Newer devices aren't even required to have a Menu button, so it pays to understand how your app's navigation (or other functionality) will work in an action bar.

Not a lot of work is required to ensure that your navigational functionality, coded for an option menu, will also work with an action bar. You've already implemented all the methods you need; what's left is to make some changes to your XML resources.

First, you need to create an emulator instance that mimics a device that uses an action bar and not a menu button. The easiest way to do that is to emulate a tablet. Fire up the Android SDK Manager command-line application from within your Android SDK installation (it's the android command found in the tools directory). Once the SDK Manager is up and running, select the Manage AVDs... option from the Tools menu. This will present you with a dialog in which you can define a new emulator or Android Virtual Device (or AVD). Select 7.0'' WSVGA (Tablet) (1024 x 600: mdpi), then set the emulator's target to at least Android 4.2.2. With that, you'll have yourself an emulator that doesn't respond to the menu button, as shown in Figure 9.

Figure 9. Creating a tablet emulator
A screenshot of selections to emulate a tablet device.

Next, start your application in that tablet instance. You should see a vertical line of three dots in the lower right corner. That looks pretty good, doesn't it? By default, Android retains the menu behavior, even in newer displays. By updating the app's XML resources you can upgrade the action bar's appearance and behavior so that it's more natural.

Start with the app's AndroidManifest.xml file, where you'll update the SDK target:

<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="17" />

Next, go into your project's Properties in Eclipse and update the Project Build Target to any version of Android higher than Android 4.2.2. Click OK and let your project rebuild itself. Then, find the menu XML file in the menu directory. Update it as follows, which will keep the item definition for Quit.

android:showAsAction="always"

Finally, if your project doesn't already have two subdirectories in the res directory named values-v11 and values-v14, create those directories. Then, in the values-v11, add the following XML file:

<resources>
 <style name="AppBaseTheme" parent="android:Theme.Holo.Light"></style>
</resources>

In the values-v14 directory, add this file:

<resources>
 <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar"></style>
</resources>

Now re-start the emulator and you should notice your new icon in the upper right corner:

Figure 10. An action bar with icons
A screenshot of the new icon, a green robot.

Now go back to the menu file in the menu directory where the quit item is defined and change showAsAction to never. Re-run your app and you should see those same three vertical dots in the upper right corner.

Don't forget to re-set

Note that if you want to keep your app target as Gingerbread, you will need to re-set your project's build target and undo the XML changes from this section. These changes are not backward compatible!


More fun with icons

So far you've added a menu option to your app targeting Gingerbread, seen that it translates pretty well to newer devices that implement the action bar, and learned how to upgrade that functionality, if you choose, with just a few updates to your app's XML.

Now let's solidify what you've learned about icons. You've done the heavy lifting of adding an icon to your app's navigation menu, so it should be no sweat to update its main icon. This icon symbolizes your app for the user, so knowing how to update and customize it is important.

I'll update the icon for Overheard Word, and you can follow along with your own app. Once again, a quick Internet search turns up a plethora of icon sites. Among them I found an interesting icon set, and one particular icon that really suits my fancy:

Figure 11. A nifty new icon
The new main icon for Overheard Word shows a writing pad and pen.

Recall that icons render differently on different device profiles. Since I want to make sure that users get a good first impression of Overheard Word, it makes sense to get the icon resolution right for my target device range. Luckily, I know a really handy site for that.

Investing in icons

It's okay to use a free icon for demonstration purposes, but I've learned that it really pays to invest in custom icons for professional apps. An icon (or icon set) embodies your app's brand, so you want it to be unique. If it's generic, or obviously amateur work, what does that lead users to conclude about your app?

Android Asset Studio (see Resources) is a Google Code project that has many helpful utilities for Android developers. One that I use a lot is Launcher Icons. All I do is click the Launcher Icons link and upload my icon. The utility generates icon files in the correct size for various device profiles, which I then download in a zip file. The file holds four directories, each containing a specific resolution and size version of the file I uploaded.

Figure 12. Launcher Icons correctly sized icon images for Android
Launcher Icons provide correctly sized icons for four different Android devices.

Next, I copy the file called ic_launcher.png from each directory into the same exact subdirectory in my app's res folder. Note that in this process, I am likely replacing the original icon file generated by Eclipse.

Finally, I re-run my app and wait till it appears in my emulator instance. I hit the Home button and check out the results: a nifty app icon that signifies (to me, anyway) that OverHeard Word is the most interesting app on any user's device!

Figure 13. Now that's iconic!
Overheard Word's new main icon looks pretty compelling in a device's app menu.

In conclusion

In this article, you got a high-level view of an Activity's lifecycle and learned how to work with it to improve you app's usage of device resources. You also learned how to define and implement navigational constructs using menus and action bars, and how to replace word buttons with icons.

All of what you learned in this article is paramount to building Android apps. Mobile development on Android is easy to pick up and is, of course, a lot of fun, but it's my hope that you also see that it is a different paradigm from the Java development you might be used to. With hundreds of thousands of apps available in Google Play and other app stores, the apps that rise to the top are typically well planned, carefully designed, and skillfully coded. There's a lot to learn!

Resources

Learn

Get products and technologies

  • The Overheard Word Github repository contains the source code used in the article.
  • Also check out Gesticulate: Android swipe detection made simple.
  • Try out the Android Launcher Icons icon generator used in the article.
  • Icons for your mobile apps: Visit ArtDesigner and Glyphish for a selection of licensed custom icons for mobile and web applications, or browse thousands of free icons using the online Icon Finder.
  • Download Android: The Android SDK provides the API libraries and developer tools you need to build, test, and debug apps for Android.
  • Download IBM developer kits: Update your system and get the latest tools and technologies here.

Discuss

  • Get involved in the developerWorks community. Connect with other developerWorks users while exploring the developer-driven blogs, forums, groups, and wikis.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Mobile development on developerWorks


  • BlueMix Developers Community

    Get samples, articles, product docs, and community resources to help build, deploy, and manage your cloud apps.

  • Mobile weekly

    Innovations in tools and technologies for mobile development.

  • DevOps Services

    Software development in the cloud. Register today to create a project.

  • IBM evaluation software

    Evaluate IBM software and solutions, and transform challenges into opportunities.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Mobile development, Java technology, Open source
ArticleID=931314
ArticleTitle=Mobile for the masses: Activities and icons in your Android application lifecycle
publish-date=05282013