Firstly, one must be aware that UI updates are only allowed in the main thread, where the UI life-cycle methods are executed. Therefore, one cannot simple start a separate Thread from the UI main thread and update interface elements. For that a special mechanism is required. In order to do so, one must:
- Start a separate Thread.
- Execute all expense jobs in the run() method of the started Thread.
- When one needs to update the UI, within the separate Thread, one needs to call the sendEmptyMessage(int) or sendMessage(Message) method of a special Handler. This Handler comes from the package android.os.Handler. Within the sendEmptyMessage(int) or sendMessage(Message) method one can, and should, update the required UI elements.
package com.progressbar;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ProgressBar;
/**
* Activity which illustrates the use of actions executed in background.
*/
public class MainActivity extends Activity
{
private ProgressBar mProgress;
private int mProgressStatus = 0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get the progress bar which will be the UI element updated while
// executing another task.
mProgress = (ProgressBar) findViewById(R.id.progressBar);
// Start lengthy operation in a background thread
Thread lenghtyTask = new Thread(new BackgroundThread());
lenghtyTask.start();
}
// Thread which executes the lengthy operation in a separate thread
// and update the UI - a progress bar.
private final class BackgroundThread implements Runnable
{
public void run()
{
while (mProgressStatus < 10)
{
// execute hard work/expensive task and update progress
// counter
mProgressStatus = doWork();
// Update the progress bar - update UI
// One can use sendMessage(Message msg) in order to send an
// specific message the the method where the UI will be updated.
mHandler.sendEmptyMessage(0);
}
}
}
// handler which updates the UI (Progress Bar)
private Handler mHandler = new Handler()
{
// This method should be implemented o order to update the UI. Any data
// that must be passed, should be put in the attribute Message msg.
public void handleMessage(android.os.Message msg)
{
if (mProgressStatus < 10)
{// update progress bar for some time
mProgress.setProgress(mProgressStatus);
} else
{
// stop progress bar
mProgress.setVisibility(ProgressBar.GONE);
}
};
};
// counter
private int counter = 0;
// method which performs hard work
private int doWork()
{
// the hard work here is stop for 1 second and update a counter.
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
return counter++;
}
}
The code above executes what was stated in the steps just mentioned. The lengthy Thread is started (step 1). Within it an expensive job is performed and the progress bar status is returned (step 2). After that, the sendEmptyMessage(int) is called. This method belongs to the handler mHandler. This handler simply update a Progress Bar while a counter is 10. After that the Progress bar stops (step 3).
As you can see the mechanism for executing an asynchronous task while updating an UI is not much complicated, as long as you know how to do it correctly.
No comments:
Post a Comment