MobileAndroidAndroid Performance: Creating a Responsive Android App

Android Performance: Creating a Responsive Android App

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Introduction

Like other major operating systems, Android has the concepts of threads and each application/process has a main thread.

The main thread is super critical to the performance of the application. The main thread is responsible for the user interface and is key to almost every other aspect of the app’s behavior.

The main thread is responsible for working with activities, services, broadcast receivers, lifecycle callbacks, and intent dispatches. Because the main thread deals with all of the above, it is the responsibility of the app developer to make sure to understand the implication of unnecessary code in the main thread that can impact the user behavior.

There are two ways in which Android protects the behavior of the main thread of the application.

1. Detection in Running Applications

There are two detecting mechanisms for detecting behavior where an application’s main thread might get stuck.

Application Not Working Dialog

If the Android system detects that the application is not responsive, it shows the “Application not working” dialog. If the system detects that the main thread is tied up for five seconds, it prompts the user with the “App name isn’t responding. Do you want to close it?” dialog. The user is asked to either wait or choose to close the application.

StrictMode Class

Android also has the programmatic capability to define policies that will help identify undesirable things happening in the application. This is very useful when used to detect application behavior on the main thread.

Blocking operations like network operators or IO operations (reading/writing tasks) can reduce app responsiveness and StrictMode will help detect this. This is important because low-cost Android devices use a common free flash file system that allows only a single system Wi-Fi file operation to occur at a time.

Because of a range of available Android devices, it becomes hard to detect all places in code where blocking operations can occur.

The StrictMode class has options to set a policy to determine which operations to monitor for, and what to do when such operations occur.

Typically, app developers can use the enableDefaults method that detects all network and IO operations on the main thread.

In our application, we can enable StrictMode when the application is running on Developer Mode to detect such contention. Here is an example to detect network calls as well as UI calls and log such behavior.

public void onCreate() {
   if (DEVELOPER_MODE) {
      StrictMode.setThreadPolicy(new
            StrictMode.ThreadPolicy.Builder()
         .detectDiskReads()
         .detectDiskWrites()
         .detectNetwork()     // or .detectAll() for all
                              // detectable problems
         .penaltyLog()
         .build());
      StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
         .detectLeakedSqlLiteObjects()
         .detectLeakedClosableObjects()
         .penaltyLog()
         .penaltyDeath()
         .build());
   }
   super.onCreate();
}

2. Offloading Work

The right way to avoid the main thread from starving for resources is to offload all non-critical work that ties up the main application thread. There are a few ways to do that.

AsyncTask Class

The beauty of the AsyncTask class is that it supports background work and UI interaction. That means it is one of the easiest ways to move work that affects the UI off the main thread.

The AsyncTask presents a common background work pattern where the work is initiated from the UI thread, work is executed on the background thread, and periodically updates the UI thread from the background thread on the progress.

AsyncTask is a abstract class that has three methods that need to be overridden:

  • doInBackground: In this method, performs the long running task
  • onProgressUpdate: In this method, provides progress feedback to the user
  • onPostExecute: In this method, provides completion feedback to the user

It takes in three parameters:

  • Represents data passed to the doInBackground method. This is a variable length array of values.
  • Represents data passed to the onProgressUpdate method. This is a variable length array of values.
  • Represents data passed to the onPostExecute. This is a single value.

Here is a simple example of how to use the AsyncTask class.

Type1 foo; Type2 bar; Type3 returnVal;

class myBackgroundWorker extends AsyncTask<Type1,
   Type 2, Type 3>
{
   Type3 doInBackground(Type1  foo)
   {
      Type2 bar1, bar2, bar3;
      someprogressMethod(bar1, bar2, bar3)
   }

   void OnProgressUpdate(Type2 ... Values)
   {
      // do some work
   }


   void onPostExecute(Type3 value)
   {
      // do some work
   }

}




myBackgroundWorker work = new
   myBackgroundWorker();
work.execute(foo, bar);

Threads

Another way to offload work is to use threads by using the Thread class. The Thread class provides support to create a separate thread of execution and accepts a reference to the Runnable interface. To start the thread, invoke the thread instance’s Start method.

One thing to note with threads is that app developers should clean up threads when the user switches away. Use the OnPause method for most cases.

Loopers and Handlers

The final approach to offload work is to use loopers and handlers. Loopers provide a message pump and use HandlerThread to create a thread with a a Looper attached. Creating a looper will free up the main thread because all UI work and most housekeeping would occur on the main thread’s message loop.

Creating a looper is often required by system services.

Handlers provide a way to process work on a looper. They can handle messages directly by overriding the handleMessage method. They also can execute Runnable implementations by calling a post method.

Summary

In this article, we learned about making responsive Android applications. I hope you have found this information useful.

About the Author

Vipul Patel is a technology geek based in Seattle. He can be reached at vipul.patel@hotmail.com. You can visit his LinkedIn profile at https://www.linkedin.com/pub/vipul-patel/6/675/508.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories