Brain Flush

August 15, 2008

Handling Long Running Operations In Google Android

Filed under: Mobile Devices, Software Development & Programming — Tags: , , — Matthias @ 12:27 pm

User interface responsiveness is a crucial thing for all applications that require user interaction, but maybe even more so when programming for mobile handsets. Google’s Android programming environment unfortunately does not provide any mechanism for handling operations that may require a fair amount of time to complete, but which in itself are not meant to be implemented as Android Services. An example for this would be network I/O in an Activity, such as posting data to (or retrieving data from) a remote Web server. Because the Android runtime will terminate any Activity that does not respond within a couple of seconds, it is impossible (and simply a bad idea anyway) to perform such tasks from within the UI main thread.

That being said, I have come up with a generic class that handles long running operations by spawning a separate thread and passing back any result or error data to the main thread using a callback mechanism. An animated progress dialog will be displayed while the operation is running. That way the user is kept informed about any program activity that may take some time to complete.

The class can be used as follows:

public class MyActivity implements LongRunningActionCallback<Void> {

    private LongRunningActionDispatcher<Void> dispatcher;

    private void startLongRunningOperation() {
        // the first argument is a reference to the current Context, in this
        // case the current Activity. The second argument is a reference to
        // the object implementing the callback method.
        this.dispatcher = new LongRunningActionDispatcher<Void>(this, this);
        dispatcher.startLongRunningAction(new Callable<Void>() {
            public Void call() throws Exception {
                // perform your actions that take a long time
                return null;
        }, "Dialog Title", "Dialog message");

    // the callback
    public void onLongRunningActionFinished(Void result, Exception error) {
        if (error != null) {
            // handle error
        } else {
            // success, work with the result, if any

This will spawn a progress dialog (not indicating any actual progress in percentage, it’s just a “busy” dialog) with the given title and message. If an exception occurred in the Callable you provided, it will be passed as the error argument to the callback, so you should always check whether it’s non-null.

Below are the source codes for both LongRunningActionDispatcher and LongRunningActionCallback.

import java.util.concurrent.Callable;

import android.content.Context;
import android.os.Handler;
import android.util.Log;

 * Use this class if you need to dispatch expensive (long running) operations
 * from your Activity. The long running operation is provided to
 * {@link startLongRunningAction} as a {@link Callable}. The result of the
 * operation and any potential exception that occurred during the call are
 * passed to {@link LongRunningActionCallback.onLongRunningActionFinished},
 * which will be called on successful or unsuccessful completion of the
 * Callable.
 * This code is in the public domain. You may use, alter, and redistribute it
 * free of any charges or obligations, with the following exceptions:
 * 1. You are not allowed to remove the statement naming the original author.
 * 2. You are not allowed to remove this license statement.
 * @author Matthias Kaeppler
public final class LongRunningActionDispatcher<ResultType> {

    private Context context;

    private LongRunningActionCallback<ResultType> callback;

     * A progress dialog shown during long-lasting operations
    private ProgressDialog progressDialog;

    private Handler finishedHandler = new Handler();

    public LongRunningActionDispatcher(Context context,
            LongRunningActionCallback<ResultType> callback) {
        this.context = context;
        this.callback = callback;

     * Invoke this method to start long running operations which may block your
     * activity and therefore the main UI thread. A progress dialog will be
     * shown while the operation is executing.
     * @param callable
     *            The callable
     * @param progressDialogTitle
     *            The progress dialog title
     * @param progressDialogMessage
     *            The progress dialog message
    public void startLongRunningAction(final Callable<ResultType> callable,
            String progressDialogTitle, String progressDialogMessage) {

        progressDialog =, progressDialogTitle,
                progressDialogMessage, true, false);

        new Thread(new Runnable() {

            public void run() {
                ResultType result = null;
                Exception error = null;
                try {
                    result =;
                } catch (Exception e) {
                    Log.e("ERROR", e.getMessage());
                    error = e;

                final ResultType finalResult = result;
                final Exception finalError = error;
       Runnable() {

                    public void run() {
                        onLongRunningActionFinished(finalResult, finalError);

    private void onLongRunningActionFinished(ResultType result, Exception error) {
        callback.onLongRunningActionFinished(result, error);
 * This code is in the public domain. You may use, alter, and redistribute it
 * free of any charges or obligations, with the following exceptions:
 * 1. You are not allowed to remove the statement naming the original author.
 * 2. You are not allowed to remove this license statement.
 * @author Matthias Kaeppler
public interface LongRunningActionCallback<ResultType> {

     * Called when the callable provided to
     * {@link LongRunningActionDispatcher.startLongRunningAction} completes.
     * @param <ResultType>
     *            The result type of
     * @param result
     *            Whatever the callable returns if it completes successfully, or
     *            null if an exception was thrown
     * @param error
     *            Whatever the callable throws if it executes in error, or null
     *            if it completed successfully
    void onLongRunningActionFinished(ResultType result, Exception error);


  1. […] for you, it just so happens that I have written a module that does exactly that. Based on my former work on this problem and an excellent article by Eric Burke (who already presented an almost-working […]

    Pingback by Android In-Sync: Handling concurrent tasks in Google Android « Brain Flush — April 8, 2009 @ 7:35 pm

  2. […] written about this two times now. I think with this third approach, which made it into this library, I finally found a […]

    Pingback by Introducing Droid-Fu for Android: BetterActivity, BetterService and BetterAsyncTask « Brain Flush — November 16, 2009 @ 9:54 pm

  3. This looks cool. It’s also quite similar to AsyncTask:

    Comment by A.B. — November 9, 2011 @ 7:16 pm

    • Sure. It’s just that AsyncTask did not exist when I wrote that. That post is 3 years old. :-)

      Comment by Matthias Käppler — November 9, 2011 @ 7:25 pm

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at

%d bloggers like this: