First time writing an AsyncTask
and I seem to have a subtle design flaw that prevents both ProgressDialog
, ProgressBar
, and even Log.d()
from working properly. I suspect that somehow I am not actually creating a new thread/task.
Short: the symptoms
A
ProgressDialog
is created in the constructor, and the code orders Android to show it inonPreExecute()
, but the dialog never shows.onProgressUpdate()
is supposed to execute whenever I callpublishProgress()
from withindoInBackground()
, correct? Well, it doesn't. Instead, it executes whendoInBackground()
completes.
Long: investigations
Things I have verified through the emulator and, when possible, on a phone:
onPreExecute()
is definitely calledthe progress bar is not reset until after
doInBackground()
completesupdate_dialog.show()
is definitely executed, but the dialog does not appear unless I remove the.dismiss()
inonPostExecute()
; I imagine dialog is, like the progress bar, not shown until afterdoInBackground()
completes, but is naturally immediately dismissedthe code will happily show dialogs when no computation is involved
doInBackground()
definitely invokespublishProgress()
when it does,
onProgressUpdate()
does not execute immediately! that is, I have a breakpoint in the function, and the debugger does not stop there until afterdoInBackground()
completes! (perhaps this is a phenomenon of the debugger, rather thandoInBackground()
, but I observe the same symptoms on a mobile device)the progress bar gets updated... only after
doInBackground()
completes everythingsimilarly, the
Log.d()
data shows up in Android Monitor only afterdoInBackground()
completes everything
and of course the dialog does not show up either in the emulator or on a device (unless I remove
.dismiss()
fromonPostExecute()
)
Can anyone help find the problem? Ideally I'd like a working dialog, but as Android has deprecated that anyway I'd be fine with a working progress bar.
Code
Here are the essentials, less the details of computation &c.:
Where I call the AsyncTask
from the main thread:
if (searching) { // this block does get executed!
Compute_Task my_task = new Compute_Task(overall_context, count);
my_task.execute(field, count, max_x, max_y);
try { result = my_task.get(); } catch (Exception e) { }
}
The AsyncTask
itself:
private class Compute_Task extends AsyncTask<Object, Integer, Integer> {
public Compute_Task(Context context, int count) {
super();
current_positions = 0;
update_dialog = new ProgressDialog(context);
update_dialog.setIndeterminate(true);
update_dialog.setCancelable(false);
update_dialog.setTitle("Thinking");
update_dialog.setMessage("Please wait");
}
protected void onPreExecute() {
super.onPreExecute();
update_dialog.show();
ProgressBar pb = ((ProgressBar) ((Activity) overall_context).findViewById(R.id.progress_bar));
pb.setMax(base_count);
pb.setProgress(0);
}
protected void onPostExecute() {
super.onPostExecute();
update_dialog.dismiss();
}
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
ProgressBar pb = ((ProgressBar) ((Activity) overall_context).findViewById(R.id.progress_bar));
pb.setMax(base_count);
pb.incrementProgressBy(1);
Log.d(tag, values[0].toString());
}
protected Integer doInBackground(Object... params) {
Integer result = compute_scores(
(boolean[][]) params[0], (Integer) params[1], (Integer) params[2], (Integer) params[3], 0)
);
return result;
}
public int compute_scores(boolean[][] field, int count, int max_x, int max_y, int level) {
int result, completed = 0;
switch(count) {
// LOTS of computation goes on here,
// including a recursive call where all params are modified
if (level == 0)
publishProgress(++completed);
}
}
ProgressDialog update_dialog;
}