Handling Lengthy Operations in Google's Android
Mobile devices are very often resource-limited. That means they usually do not have the CPU power, vast memory, or storage space commonly seen in modern computers. However, sometimes complicated operations are still required to perform many features currently used on these devices. Android engineers lay out some important rules in the design philosophy; you will focus on the part about how to make sure your software is responsive enough without interfering with the main thread and inadvertently causing the system to pop up an ANR (Application Not Responding) dialog. Furthermore, a message handling mechanism is introduced to post back the result and update the view in the main thread—the device screen users operate on most of the time.
What Google APIs Are Used?
Because you are going to implement complicated operations in child threads, the usual concurrent class used in the Java threading package java.lang.Thread is used. The calling sequence and life cycle of a thread is identical to the traditional Java concept. For convenience reasons, a progress dialog is utilized to keep track of the progress. One thing to note is that Android's progress range is between 0 and 10000. It is from the android.app.ProgressDialog package.
Classes inside the android.os.Message package are used to define messages to be put in the MessageQueue for scheduled execution of a Runnable object. A Message must be processed by a Handler in the MessageQueue from the android.os.Handler package. A Handler is bound to the thread/message queue that creates it. Messages will be processed in the order they come out of the message queue. There are two main uses for a Handler: to schedule messages and runnables to be executed and to enqueue an action to be performed on a different thread.
ANR—Application Not Responding
The screen shot illustrated in Figure 1 displays the typical ANR dialog automatically popped up by the Android platform. When and why does it happen? In Android, Activity Manager and Window Manager system services monitor the application responsiveness and issue the ANR dialog if the main view detects no response to an input event over five seconds or an intent receiver has not finished executing over ten seconds. This is the main reason behind this article because this inadvertent and unpleasant ANR dialog not only symbolizes poor software design, but also rubs users the wrong way.
Figure 1: Application Not Responding (ANR) dialog
Android's Suggestions About Writing Efficient and Responsive Code
Before you start working on your solution in an example, there are some notes from Android experts you should pay attention to. To stress the importance of designing an Android application, the Android web site highlights some recommendations I think are very beneficial to all developers. After all, learning how to do things the right way from the very beginning cuts down significant development and maintenance time and effort. Besides, it does bring along the advantages of enhancing users' experience. For more details about design philosophy, please see http://code.google.com/android/toolbox/philosophy.html.
There are three key characteristics for an excellent user experience: fast, responsive, and seamless.
- Fast: Code needs to be efficient enough. There are some key points mentioned:
- Do not allocate memory if you can avoid it.
- Do not do work with what you do not need to.
- Avoid creating objects when possible.
- Use native methods.
- Prefer static over virtual methods.
- Access variables directly within a class not through info getters.
- Accessing object fields is much slower than accessing local variables.
- Declare constants final.
- Use for-each syntax with caution
- Avoid enums
- Declare fields and methods accessed by inner classes to have package scope.
- Avoid floating point.
- Check approximate run times for basic actions.
- Responsive: Applications that tend to be slow, hang, freeze, or take too long to process input for noticeable periods are considered unresponsive. They usually blocks on I/O operations. Potentially long running operations should be done in child threads. Your main thread should provide a Handler for child threads to post back to upon completion. Your application should start a Service if a potentially long running action needs to be taken in response to an Intent broadcast.
- Seamless: Sometimes a background process (for example, a Service or IntentReceiver) that pops up a UI may seem harmless but it could be annoying for users and in some cases result in data loss. The Android standard is to use a Notification for such events and leave users in control. Here are the tips for writing a seamless application:
- Save the work in progress.
- Create a ContentProvider to expose your data.
- Do not interrupt users when they are talking.
- Avoid huge Activity.
- Use a theme for user interface.
- Make resolutions flexible.
- Assume that the network is slow.
- Keep different keyboard layouts in mind.
- Save battery power.