У меня есть класс, расширяющий AsyncTask, который предназначен для использования в качестве универсального класса диспетчера задач для моего приложения.
Проблема. Странное поведение заключается в том, что диалоговое окно прогресса появляется, но никогда не закрывается.
Я уверен, что onPostExecute() вызывается для каждого экземпляра задачи, так как любые операторы Log.d("","") срабатывают, если они размещены здесь, даже сообщения Toast появляются из этого метода, но я не могу закрыть статический диалог.
Я понимаю, что AsyncTask (ы) имеют доступ к потоку пользовательского интерфейса только в двух местах [onPreExecute() и onPostExecute()], поэтому я думаю, что пытаться закрыть диалоговое окно в runOnUiThread() не нужно.
Все вызовы executeTask() выполняются из разных методов onCreate() различных действий, которым необходимо получить некоторые данные по сети, прежде чем заполнять некоторые из их элементов пользовательского интерфейса, и я всегда передаю контекст текущего действия задачам.
Поскольку я не переключаю действия до тех пор, пока связанные задачи не будут завершены, я считаю, что объекты контекста действия все еще действительны (я ошибаюсь, предполагая это???) Я никогда не обнаруживал, что какой-либо из них имеет значение null во время отладки.
Может ли это быть проблемой времени? Я также заметил, что в большинстве случаев DDMS показывает, что все задачи завершены до отображения активности. Если я использую
new Handler().postDelayed(runnable_which_calls_these_tasks,10);
в onCreate() и добавляю код задержки в foo_X(), действия отображаются без каких-либо задержек, но диалоговое окно просто не будет закрываться().
Я прочитал довольно много статей по этому вопросу, но до сих пор не могу понять, где именно я ошибаюсь. Я не хочу определять каждую задачу как private inner class Task1 extends AsyncTask<>
во всех моих классах действий, и я бы не хотел (если только это не единственное решение) загружать объект приложения со всеми ссылками на действия, как упоминалось в этом обсуждении: Действительно ли AsyncTask концептуально ошибочен или я просто что-то упустил?.
Я потратил на это неделю и совершенно ничего не понимаю :( Было бы здорово, если бы кто-нибудь мог направить меня и сообщить, что мне не хватает.
Ниже приводится определение класса: [Я удалил некоторые нерелевантные приложения код для ясности]
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();
}
}
}