Pergunta

Estou começando a pensar que, para fazer com que um ProgressDialog trabalhe, o assíncrono deve ser uma classe interna dentro de uma classe de atividades. Verdadeiro? [Editado muito mais tarde ... A resposta é falsa e não tenho certeza se isso é um bug ou o quê. Estou usando o Android 1.5. Vou ler sobre serviços.

Eu tenho uma atividade que usa um banco de dados para manipular informações. Se o banco de dados for preenchido, tudo estiver bem. Se não estiver preenchido, preciso baixar informações de um site, preencher o banco de dados e acessar o banco de dados povoado para concluir as visualizações no OnCreate.

O problema é sem alguns meios para determinar quando o thread do assíncrono terminou a preenchimento do banco de dados, recebo a seguinte mensagem de erro de fechamento da força: Desculpe! O aplicativo parou inesperadamente. Eu clico no botão Force Fechar, o thread de assínctas de fundo continua funcionando, o banco de dados é preenchido e tudo funciona bem.

Preciso me livrar dessa mensagem de erro e precisar de ajuda sobre como fazer isso. Aqui está algum código PSUDO:

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

Em um arquivo separado:

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
    }
 }

Aqui está o rastreamento da pilha do emulador:

----- 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 -----

O que estou fazendo errado?

Sr. Snowflake,

Tentou:

@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");
      }
    });
}

Atividade.

Penso que preciso preencher a atividade estende e depois criar uma classe privada no FillDB estendendo asyncTask? Isso não vai funcionar. Nenhuma garantia quando a atividade do FILDDB começará e não pode usar o StartActivityForResult, pois nenhum resultado é retornado do AsyncTask quando for concluído.

ATUALIZAÇÃO: Tentei criar uma classe privada na classe de chamada. Ainda não pode mostrar um ProgressDialog. Um dos erros é: não consegue adicionar janela - o token nulo não é para um aplicativo. Não tenho ideia do que o token está sendo referido.

Foi útil?

Solução 2

Desisti no ASYNCTASK e usei um manipulador para manusear o fio. Tudo está bem.

Não tenho certeza se é um bug em 1.5 com asynctask ou outra coisa que eu não fiz.

Outras dicas

Você já pensou em substituir o método onCreateDialog () para implementar suas caixa de diálogo? É fácil criá -los e controlá -los dessa maneira, pois o Android faz a maior parte do trabalho para você. Eu tenho um exemplo abaixo fazendo exatamente o que você está tentando fazer.

http://pastie.org/880540

Eu estava tendo o mesmo problema que o OP for em algum momento com uma assíncada pública (externa). Ao pesquisar sobre a mensagem de erro "tentou adicionar janela com token que não é de aplicação", descobri que o problema está na definição do contexto que está sendo aprovado no construtor da assíncrone. O contexto que deve ser aprovado é "isso", não isso.getApplicationContext () ou this.getBaseContext (). Isso resolveu meu problema.

Tente correr

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

como um argumento executável para a atividade.RunonuithRead (). Os elementos da interface do usuário devem ser criados e manipulados no thread da interface do usuário. Eu acho que isso também é verdade para Dialogs.

Editar] Código:

Activity.this.runOnUiThread(new Runnable() {
  public void run() {
    ProgressDialog progressDialog = new ProgressDialog(context);
    //crashes with the following line
    progressDialog.show(context, "Working..", "Retrieving info");
  }
};
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top