ProgressDialog не работает во внешнем AsyncTask - PullRequest
9 голосов
/ 21 марта 2010

Я начинаю думать, что для того, чтобы заставить ProgressDialog работать, AsyncTask должен быть внутренним классом в классе Activity.Правда?[Отредактировано намного позже ... ответ - Ложь, и я не уверен, что это ошибка или что-то в этом роде.Я использую Android 1.5.Я собираюсь прочитать о Службах.]

У меня есть действие, использующее базу данных для манипулирования информацией.Если база данных заполнена, все хорошо.Если он не заполнен, то мне нужно загрузить информацию с веб-сайта, заполнить базу данных, а затем получить доступ к заполненной базе данных, чтобы завершить просмотры в onCreate.

Проблема заключается в отсутствии каких-либо средств для определения окончания потока AsyncTask.Заполняя базу данных, я получаю следующее сообщение об ошибке принудительного закрытия: Извините!Приложение неожиданно остановилось.Я нажимаю кнопку «Принудительно закрыть», фоновый поток AsyncTask продолжает работать, база данных заполняется, и все работает нормально.

Мне нужно избавиться от этого сообщения об ошибке и нужна помощь, как это сделать.,Вот некоторый код псевдо:

public class ViewStuff extends Activity
{
  onCreate
  { 
    if(database is populated)
      do_stuff
    else
    {
      FillDB task = null;
      if(task == null || task.getStatus().equals(AsyncTask.Status.FINISHED))
       {                
         task = new FillDB(context);
         task.execute(null);
       }
    }

  continue with onCreate using information from database to properly display 

 } // end onCreate
} // end class

В отдельном файле:

public class FillDB extends AsyncTask<Void, Void, Void>
{
    private Context context;

    public FillDB (Context c)  //pass the context in the constructor
{
    context = c;
}

    public void filldb ()
    {
      doInBackground();
    }

    @Override
    protected void onPreExecute()
    {          
       ProgressDialog progressDialog = new ProgressDialog(context);
       //crashes with the following line
       progressDialog.show(context, "Working..", "Retrieving info");
    }

    @Override
    protected Void doInBackground(Void... params)
    {
  // TODO Auto-generated method stub

try
     etc etc etc
    }
 }

Вот трассировка стека от эмулятора:

----- pid 846 at 2010-03-21 19:58:25 -----
Cmd line: com.trial

DALVIK THREADS:
"main" prio=5 tid=3 NATIVE
 | group="main" sCount=1 dsCount=0 s=0 obj=0x40018e70
 | sysTid=846 nice=0 sched=0/0 handle=-1098855268
 at android.os.BinderProxy.transact(Native Method)
 at      android.app.ActivityManagerProxy.handleApplicationError(ActivityManagerNative.java:2103)
 at com.android.internal.os.RuntimeInit.crash(RuntimeInit.java:302)
 at   com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:75)
 at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:887)
 at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:884)
 at dalvik.system.NativeStart.main(Native Method)

 "Binder Thread #3" prio=5 tid=15 NATIVE
 | group="main" sCount=1 dsCount=0 s=0 obj=0x43733d88
 | sysTid=852 nice=0 sched=0/0 handle=1486928
 at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #2" prio=5 tid=13 NATIVE
 | group="main" sCount=1 dsCount=0 s=0 obj=0x437313c8
 | sysTid=851 nice=0 sched=0/0 handle=1492472
 at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #1" prio=5 tid=11 NATIVE
 | group="main" sCount=1 dsCount=0 s=0 obj=0x4372b9b0
 | sysTid=850 nice=0 sched=0/0 handle=1492664
 at dalvik.system.NativeStart.run(Native Method)

"JDWP" daemon prio=5 tid=9 VMWAIT
 | group="system" sCount=1 dsCount=0 s=0 obj=0x4372a2a0
 | sysTid=849 nice=0 sched=0/0 handle=1490176
 at dalvik.system.NativeStart.run(Native Method)

"Signal Catcher" daemon prio=5 tid=7 RUNNABLE
| group="system" sCount=0 dsCount=0 s=0 obj=0x4372a1e8
| sysTid=848 nice=0 sched=0/0 handle=1487888
 at dalvik.system.NativeStart.run(Native Method)

"HeapWorker" daemon prio=5 tid=5 VMWAIT
 | group="system" sCount=1 dsCount=0 s=0 obj=0x427d03c0
 | sysTid=847 nice=0 sched=0/0 handle=1487592
 at dalvik.system.NativeStart.run(Native Method)

 ----- end 846 -----

Что я делаю неправильно?

Мистер.Снежинка,

Пробовал:

@Override
protected void onPreExecute()
{

Activity.this.runOnUiThread(new Runnable() {
      public void run() {
        ProgressDialog progressDialog = new ProgressDialog(context);
        //crashes with the following line
        progressDialog.show(context, "Working..", "Retrieving info");
      }
    });
}

Activity.this помечен как ошибка: нет включающего экземпляра типа Activity доступен в области действия

Я думаю, мне нужноFillDB расширяет Activity, а затем создает закрытый класс в FillDB, расширяющий AsyncTask?Это не сработает.Нет уверенности в том, что начнется действие FillDB, и он не сможет использовать startActivityForResult, поскольку по завершении AsyncTask не возвращает никакого результата.

Обновление: Попытка создания частного класса в вызывающем классе.Все еще не могу показать ProgressDialog.Одна из ошибок: Невозможно добавить окно - нулевой токен не для приложения.Я понятия не имею, о каком токене идет речь.

Ответы [ 4 ]

2 голосов
/ 22 марта 2010

Рассматривали ли вы переопределение метода onCreateDialog () для реализации ваших диалогов? Их легко создавать и контролировать, так как Android делает большую часть работы за вас. У меня есть пример ниже, делающий именно то, что вы пытаетесь сделать.

http://pastie.org/880540

2 голосов
/ 29 марта 2010

Я отказался от AsyncTask и использовал обработчик для обработки потока. Все хорошо.

Не уверен, что это ошибка в 1.5 с AsyncTask или что-то еще, что я не сделал.

0 голосов
/ 21 июля 2010

У меня довольно долго была та же проблема, что и у OP с публичной (внешней) AsyncTask.Исследуя сообщение об ошибке «Попытка добавить окно с токеном, не относящимся к приложению», я обнаружил, что проблема заключается в настройке контекста, передаваемого в конструктор AsyncTask.Контекст, который должен быть передан - это «this», а не this.getApplicationContext () или this.getBaseContext ().Это решило мою проблему.

0 голосов
/ 21 марта 2010

Попробуйте запустить

   ProgressDialog progressDialog = new ProgressDialog(context);
   //crashes with the following line
   progressDialog.show(context, "Working..", "Retrieving info");

как исполняемый объект в качестве аргумента Activity.runOnUiThread (). Элементы пользовательского интерфейса должны создаваться и обрабатываться в потоке пользовательского интерфейса. Я думаю, это также верно для Dialog с.

[править] Код:

Activity.this.runOnUiThread(new Runnable() {
  public void run() {
    ProgressDialog progressDialog = new ProgressDialog(context);
    //crashes with the following line
    progressDialog.show(context, "Working..", "Retrieving info");
  }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...