I have an Activity with a button that starts a long running task. I perform the task using an AsyncTask and display a determinate ProgressBar that is updated as the task progresses. Everything works fine the first time the task is run, but on subsequent runs the dialog appears, but is already at 100% and 100/100. I’m overriding both onCreateDialog and onPrepareDialog in my Activity. I presumed that using setProgress(0) would reset the dialog, but this isn’t working. I use showDialog in the AsyncTask’s onPreExecute method and dismissDialog in the AsyncTask’s onPostExecute. The only way I’ve been able to get the dialog to reset is by using removeDialog in onPostExecute, but I would rather not recreate the dialog as I’m going to be reusing several times. The relevant code is below. This is on API level 10.
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case PROGRESS_DIALOG:
progressDialog = new ProgressDialog(ProtoBufSerializationTestActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(true);
progressDialog.setMax(100);
progressDialog.setMessage("Testing...");
return progressDialog;
default:
return null;
}
}
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
switch (id) {
case PROGRESS_DIALOG:
ProgressDialog tmp = (ProgressDialog)dialog;
tmp.setProgress(0);
tmp.setSecondaryProgress(0);
return;
default:
Log.e("test", "Unknown dialog requested");
}
}
private class SerializationTestTask extends AsyncTask<Void, Integer, Long> {
@Override
protected void onPreExecute() {
showDialog(PROGRESS_DIALOG);
}
@Override
protected Long doInBackground(Void... params) {
long accumulator = 0;
int totalSize = 0;
for (int i = 0; i < 10000; i++) {
final long start = System.nanoTime();
//code to be timed
final long end = System.nanoTime();
accumulator += end - start;
if (i % 100 == 0) {
publishProgress(i);
}
}
return accumulator;
}
@Override
protected void onPostExecute(Long aLong) {
dismissDialog(PROGRESS_DIALOG);
results.setText(String.format("Serialized Message 10000 times.\nAverage time to serialize %.3fms", (double) aLong / 1e10));
}
@Override
protected void onProgressUpdate(Integer... values) {
progressDialog.incrementProgressBy(1);
}
Edit After taking @Arhimed’s suggestion I ended up with the following code. It is much simpler. I could have used DialogFragment, but I don’t think it is necessary in this case.
private class SerializationTestTask extends AsyncTask<Void, Integer, Long> {
private ProgressDialog dialog;
@Override
protected void onPreExecute() {
dialog = ProgressDialog.show(ProtoBufSerializationTestActivity.this, "Serialization Test", "Testing...", false);
}
@Override
protected Long doInBackground(Void... params) {
long accumulator = 0;
int totalSize = 0;
for (int i = 0; i < 10000; i++) {
final long start = System.nanoTime();
//code to be timed
final long end = System.nanoTime();
accumulator += end - start;
if (i % 100 == 0) {
publishProgress(i);
}
}
return accumulator;
}
@Override
protected void onPostExecute(Long aLong) {
dialog.dismiss();
results.setText(String.format("Serialized Message 10000 times.\nAverage time to serialize %.3fms", (double) aLong / 1e10));
}
@Override
protected void onProgressUpdate(Integer... values) {
dialog.incrementProgressBy(1);
}
}
It is impossible to use
ProgressDialogin that way. YourAsyncTaskshould create a new instance each time.