Hans Dulimarta

Android ProgressDialog With Delay

A progress dialog gives a visual feedback to a user who is waiting for a relatively long task to complete. When the task involves retrieving external data from the network, the completion time can be unpredictable and it may vary significantly. On the extreme case when the task finishes in a blink of an eye, it may be unnecessary to show the progress dialog altogether.

The current set of Android widgets does not provide an easy way to postpone displaying a dialog, a feature that can be useful to selectively show a dialog only when the task may potentially require longer time to complete. Combining this feature with Android AsyncTask, a progress dialog that provides a “showAfter(millisecond_delay)” functionally can be used as follow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void onPreExecute()
{
    /* 800 msec delay */
    progress = DelayedProgressDialog.show (..., 800);
}

void doInBackground(....)
{

}

void onPostExecute(Void unused)
{
    if (progress.isShowing())
        progress.dismiss();
    progress.cancel();  /* remove the dialog */
}

In the above hypothetical example, the dialog will show up approximately 800msec after it is built. When the background task finished in less than 800 ms, the dialog will never show up.

Implementing the Code

The following class inherits the ProgressDialog class and defines a static show() method (similar to that of ProgressDialog except with a fourth parameter to control the millisecond delay before the dialog actually appears). The delayed appearance of the dialog is handled by the Handler#postDelayed method.

When the dialog is not needed anymore, its cancel() method can be invoked, thus removing it from the Handler’s message queue.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class DelayedProgressDialog extends ProgressDialog {
    private static Handler dialogHandler;
    private Runnable runner;

    static {
        dialogHandler = new Handler();
    }

    public DelayedProgressDialog (Context c)
    {
        super (c);
    }

    public static ProgressDialog show (Context c,
        CharSequence title, CharSequence msg,
        long delayMilliSec)
    {
        final DelayedProgressDialog pd = new DelayedProgressDialog(c);
        pd.setTitle (title);
        pd.setMessage (msg);
        pd.setCancelable (true);
        pd.runner = new Runnable() {

            public void run() {
                try {
                    pd.show();
                }
                catch (Exception e) {
                    /* do nothing */
                }
            }
        };
        dialogHandler.postDelayed (pd.runner, delayMilliSec);
        return pd;
    }

    @Override
    public void cancel()
    {
        dialogHandler.removeCallbacks (runner);
        super.cancel();
    }
}

The sample Android code can be viewed on my GitHub Gists