I have a class which extends AsyncTask, which is intended to serve as a generic task manager class for my application.
Problem:The strange behavior is that the progress dialog shows up, but is never dismissed.
-
I am sure that onPostExecute() gets called for every task instance, as any Log.d(“”,””) statements fire if placed in here, even the Toast messages show up from within this method, but I am not able to dismiss the static dialog.
-
I understand that AsyncTask(s) have access to UI thread at only 2 places [onPreExecute() and onPostExecute()], so I think trying to dismiss the dialog in runOnUiThread() is unnecessary.
-
All calls to executeTask() are made from different onCreate() methods of different activities that need to fetch some data over network before populating some of their UI elements, and I always pass the current activity’s context to the tasks.
-
As I do not switch activities until after the related tasks are completed, I believe the activity context objects are still valid (am I wrong to have assumed this???) I have never found any of them to be null while debugging.
-
Could this be a timing issue? I have also observed that most of the times DDMS shows all tasks get completed before the activity is displayed. If I use
new Handler().postDelayed(runnable_which_calls_these_tasks,10);in the onCreate(), and add delaying code in foo_X(), the activities are displayed without any delay, but the dialog will just not dismiss().
I have read through quite a number of articles on this issue but am still not able to figure out exactly where am I going wrong. I do not want to define each task as private inner class Task1 extends AsyncTask<> in all of my activity classes and I would not want to (unless this is the only solution) load my application object with all activity references either as mentioned in this discussion: Is AsyncTask really conceptually flawed or am I just missing something?.
I have spent a week on this and am absolutely clueless 🙁 It would be great if someone can guide me, and let me know what am I missing.
Following is the class definition: [I’ve removed some irrelevant application specific code for clarity]
public class NetworkTask extends AsyncTask<Void, Integer, Boolean> {
private Context UIcontext;
private int operationType;
private static ProgressDialog dialog;
private static int taskCount;
private NetworkTask(int operationType Context context){
this.UIcontext = context;
this.operationType = operationType;
if (taskCount++ == 0)
dialog = ProgressDialog.show(context,"","Loading...");
}
public static Boolean executeTask(int operationType, Context context) {
return new NetworkTask(operationType, context).execute().get();
}
@Override
protected void onPreExecute(){
super.onPreExecute();
if (taskCount == 1)
dialog.show();
}
@Override
protected Boolean doInBackground(Void... arg0) {
switch(operationType){
case TYPE_1:
foo1();
break;
case TYPE_2:
foo2();
break;
case TYPE_3:
foo3();
break;
case TYPE_4:
foo4();
break;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
taskCount--;
if (dialog.isShowing() && taskCount == 0){
dialog.dismiss();
}else {
Toast.makeText(UIcontext, "Task#"+ operationType+", m done, but there are "+taskCount+" more", 5).show();
}
}
}
Edited:
Mystery solved – this one was giving me a bit of trouble. There were a few problems:
The main problem why dialog was not showing was
NetworkTask.get(). This is a blocking call that waits for the whole NetworkTask to finish. During that time it blocks UI thread so nothing is drawn (also other UI elements are unresponsive). Removeget():The
show()on ProgressDialog is called twice. This shows two dialogs, one after another. Removeshow()insideonPreExecute().ProgressDialog is modal – it prevents changing UI until it is done.
Toast.makeText()are called beforedialog.dismiss()but since dialog is blocking drawing to screen, they get queued and are shown after dialog is dismissed.super.onPostExecute(result)andsuper.onPreExecute()are redundant so can be removed.I can post the whole working code if you have trouble with it.