Jump to content

How to handle threads in Android, and what you need to watch for

0
  chco's Photo
Posted May 14 2011 10:11 PM

The excerpt below from Learning Android offers a look at working with threads in Android.
A thread is a sequence of instructions executed in order. Although each CPU can process only one instruction at a time, most operating systems are capable of handling multiple threads on multiple CPUs, or interleaving them on a single CPU. Different threads need different priorities, so the operating system determines how much time to give each one if they have to share a CPU.

The Android operating system is based on Linux and as such is fully capable of running multiple threads at the same time. However, you need to be aware of how applications use threads in order to design your application properly.

Single Thread

By default, an Android application runs on a single thread. Single-threaded applications run all commands serially, meaning the next command is not completed until the previous one is done. Another way of saying this is that each call is blocking.

This single thread is also known as the UI thread because it’s the thread that processes all the user interface commands as well. The UI thread is responsible for drawing all the elements on the screen as well as processing all the user events, such as touches on the screen, clicks of the button, and so on. The image below shows the execution of our code on a single UI thread.

Single-threaded execution

Attached Image


The problem with running StatusActivity on the single thread is our network call to update the status. As with all network calls, the time it takes to execute is outside of our control. Our call to twitter.updateStatus() is subject to all the network availability and latency issues. We don’t know whether the user is on a super-fast WiFi connection or is using a much slower protocol to connect to the cloud. In other words, our application cannot respond until the network call is completed.

Note: The Android system will offer to kill any application that is not responding within a certain time period, typically around five seconds for activities. This is known as the Application Not Responding dialog, or ANR for short.

Application Not Responding dialog

Attached Image


Multithreaded Execution

A much better solution is to have the potentially long operations run on a separate thread. When multiple tasks run on multiple threads at the same time, the operating system slices the available CPU so that no one task dominates the execution. As a result, it appears that multiple tasks are running in parallel at the same time.

In our example, we could put the actual network call for updating our status in the cloud in a separate thread. That way our main UI thread will not block while we’re waiting for the network, and the application will appear much more responsive. We tend to talk of the main thread as running in the foreground and the additional threads as running in the background. They’re really all equal in status, alternating their execution on the device’s CPU, but from the point of view of the user, the main thread is in the foreground because it deals with the UI. The image below shows the execution of our code’s two threads—the main UI thread, as well as the auxiliary thread we use to perform potentially long-running network calls.

Multithreaded execution

Attached Image


There are multiple ways of accomplishing multithreading. Java has a Thread class that allows for many of these operations. We could certainly use any of the regular Java features to put the network call in the background.

However, using the standard Java Thread class is problematic because another thread is not allowed to update the elements in the main UI thread. This makes sense because to update the UI thread, we would need to synchronize with the current state of its objects, and that would be a job on its own.

In addition to standard Java threading support, Android provides the utility class AsyncTask specifically designed for this purpose.

AsyncTask

AsyncTask is an Android mechanism created to help handle long operations that need to report to the UI thread. To take advantage of this class, we need to create a new subclass of AsyncTask and implement the doInBackground(), onProgressUpdate(), and onPostExecute() methods. In other words, we are going to fill in the blanks for what to do in the background, what to do when there’s some progress, and what to do when the task completes.

StatusActivity.java, version 2


package com.marakana.yamba1;

import winterwell.jtwitter.Twitter;
import winterwell.jtwitter.TwitterException;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class StatusActivity2 extends Activity implements OnClickListener {
  private static final String TAG = "StatusActivity";
  EditText editText;
  Button updateButton;
  Twitter twitter;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.status);

    // Find views
    editText = (EditText) findViewById(R.id.editText);
    updateButton = (Button) findViewById(R.id.buttonUpdate);
    updateButton.setOnClickListener(this);

    twitter = new Twitter("student", "password");
    twitter.setAPIRootUrl("http://yamba.marakana.com/api");
  }

  // Asynchronously posts to twitter
  class PostToTwitter extends AsyncTask<String, Integer, String> { // 
    // Called to initiate the background activity
    @Override
    protected String doInBackground(String... statuses) { // 
      try {
        Twitter.Status status = twitter.updateStatus(statuses[0]);
        return status.text;
      } catch (TwitterException e) {
        Log.e(TAG, e.toString());
        e.printStackTrace();
        return "Failed to post";
      }
    }

    // Called when there's a status to be updated
    @Override
    protected void onProgressUpdate(Integer... values) { // 
      super.onProgressUpdate(values);
      // Not used in this case
    }

    // Called once the background activity has completed
    @Override
    protected void onPostExecute(String result) { // 
      Toast.makeText(StatusActivity2.this, result, Toast.LENGTH_LONG).show();
    }
  }

  // Called when button is clicked
  public void onClick(View v) {
    String status = editText.getText().toString();
    new PostToTwitter().execute(status); // 
    Log.d(TAG, "onClicked");
  }

}


At this point, when the user clicks on the Update Status button, our activity will create a separate thread using AsyncTask and place the actual network operation on that thread. When done, the AsyncTask will update the main UI thread by popping up a Toast message to tell the user that the operation either succeeded or failed. This approach makes our application much more responsive, and users should never get the "Application Not Responding: Force Close or Wait" message shown above. At this point, our application looks like the image below when running.

StatusActivity, part 1

Attached Image


Learning Android

Learn more about this topic from Learning Android.

If you're new to the Android mobile operating system, Learning Android is the perfect way to master the fundamentals. This gentle introduction shows you how to use Android's basic building blocks to develop user interfaces, store data, and more. You'll build an example application throughout the course of book, adding new features with each chapter. You'll also build your own toolbox of code patterns that will help you program any type of Android application with ease.

See what you'll learn


Tags:
1 Subscribe


2 Replies

0
  Android Example's Photo
Posted Feb 02 2013 11:03 AM

Nice one..........

Also found one good tutorial on
http://androidexampl...&aid=52&aaid=77
0
  Android Example's Photo
Posted Feb 02 2013 11:05 AM

You can also see on

http://androidexampl...&aid=59&aaid=84