By default, in Android, a single thread is used to run every application component, such as Activity and Service. If you perform a long running task from an event handler, messages to all other components will be delayed. Generally speaking, spawning a separate thread for long running work is recommended. At the same time, you do not always need the complication of a separate thread. In this article below, we will show you how to use the Handler framework to carry out a long work in small chunks using the solitary main thread of the application. You can even show a progress dialog to keep the user notified.
Basics of the Handler Framework
In Android, you can use an android.os.Handler object to post a message in the event queue of the thread where the handler is created. Keep in mind, all UI events are processed in the main thread of the application. If you create a handler in that thread then all messages for that handler will be mixed with the UI events in the queue.
The Handler class has many sendXXX() methods to queue a message. We will use the very basic sendEmptyMessage(int what) method.
When a message arrives for a Handler, the handleMessage(Message msg) method is called.
Getting Started
In your activity that will do the long running work, add these member variables.
ProgressDialog mProgressDialog; int mProgressAmount = 0;
Create another member variable for the Handler.
final Handler mHandler = new Handler() { public void handleMessage(Message msg) { try { Log.v("Handler", "Progress: " + mProgressAmount); Thread.sleep(500); } catch (Exception e) { } mProgressAmount += 10; if (mProgressAmount < 100) { sendEmptyMessage(0); } else { mProgressDialog.dismiss(); } } };
The handleMessage method performs the long running operation in small chunks. Work is simulated here by the Thread.sleep() method. If further work is needed, we send another message for the handler. If work is done, we dismiss the progress dialog.
Finally, from the on click event handler of a button or some other event handler, we kick off the work.
public void onClick(View arg0) { mProgressAmount = 0; mProgressDialog = ProgressDialog.show(this, "", "Loading. Please wait...", true); mHandler.sendEmptyMessage(0); }
Showing Progress Amount
We can easily use a horizontal progress bar. Change the way the progress bar dialog is created.
public void onClick(View arg0) { mProgressAmount = 0; mProgressDialog = new ProgressDialog(this); mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mProgressDialog.setMessage("Loading. Please wait..."); mProgressDialog.show(); mHandler.sendEmptyMessage(0); }
In the handler, increment the progress amount.
mProgressAmount += 10; mProgressDialog.incrementProgressBy(10);
Analysis
Here we see a simple technique to break up a long running work in small pieces and doing all the work in the main thread of the application. The progress bar dialog prevents any interaction with the activity while the work is in progress.
If, in the middle of the work, user clicks the back button, the progress dialog will be dismissed. But the work will continue. User is able to interact with the Activity at this point. This can lead to undesirable behavior. To prevent this from happening, make the progress dialog non-cancelable.
mProgressDialog.setCancelable(false);