Domanda

Sto cominciando a pensare che per ottenere un ProgressDialog a lavorare l'AsyncTask deve essere una classe interna all'interno di una classe di attività. Vero? [Modificato molto più tardi ... la risposta è falsa e non sono sicuro se questo è un bug o cosa. Sto utilizzando Android 1.5. Io vado a leggere su servizi.]

Ho un'attività gli usi di un database per manipolare le informazioni. Se il database è popolato tutto va bene. Se non è popolata poi ho bisogno di scaricare le informazioni da un sito web, popolare il database, quindi accedere al database popolato per completare le viste in onCreate.

Il problema è che senza qualche mezzo per determinare quando il filo AsyncTask ha terminato il popolamento del database, ottengo il seguente messaggio di errore Forza In prossimità: Sorry! L'applicazione è stata interrotta inaspettatamente. Clicco sul pulsante Forza Chiudi, il thread in background AsyncTask continua a lavorare, il database viene popolato, e tutto funziona bene.

Ho bisogno di sbarazzarsi di quel messaggio di errore e bisogno di aiuto su come fare questo. Ecco po 'di codice pseudo:

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

In un file separato:

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

Ecco la traccia dello stack dall'emulatore:

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

Che cosa sto facendo di sbagliato?

Mr. Fiocco di neve,

Hai provato:

@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 è contrassegnata come un errore: Nessuna istanza allegando del tipo di attività è accessibile in ambito

sto pensando che ho bisogno di FillDB estende Activity quindi creare una classe privata all'interno FillDB estende AsyncTask? Che sogliono' di lavoro. Nessuna assicurazione quando l'attività FillDB avrà inizio e non può usare startSubActivity dal momento che nessun risultato viene restituito da AsyncTask quando è completato.

Aggiornamento: Ho provato la creazione di una classe privata nella classe chiamata. Ancora non è possibile mostrare un ProgressDialog. Uno degli errori è: Impossibile aggiungere finestra - nulla pedina non è per un'applicazione. Non ho idea di che cosa gettone viene indicato.

È stato utile?

Soluzione 2

ho rinunciato a AsyncTask e usato un gestore per gestire la discussione. Tutto è buono.

Non so se si tratta di un bug in 1.5 con AsyncTask o qualcos'altro che non ho fatto.

Altri suggerimenti

Avete considerato l'override del metodo onCreateDialog () per implementare le finestre di dialogo? E 'facile da creare e controllare loro in questo modo come Android fa la maggior parte del lavoro per voi. Ho un esempio di seguito facendo esattamente quello che stai cercando di fare.

http://pastie.org/880540

ho avuto lo stesso problema di OP per parecchio tempo con un pubblico (esterno) AsyncTask. Quando la ricerca sul messaggio di errore "ha tentato di aggiungere finestra con token non di applicazione", ho scoperto che il problema è nella creazione di un contesto che viene passata nel costruttore della AsyncTask. Il contesto che dovrebbe essere passato è "questo", non this.getApplicationContext () o this.getBaseContext (). Che ha risolto il mio problema.

Provare a eseguire

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

come un eseguibile come argomento di Activity.runOnUiThread (). Gli elementi dell'interfaccia utente devono essere creati e manipolati nel thread UI. Credo che questo è vero anche per Dialogs.

[modifica] Codice:

Activity.this.runOnUiThread(new Runnable() {
  public void run() {
    ProgressDialog progressDialog = new ProgressDialog(context);
    //crashes with the following line
    progressDialog.show(context, "Working..", "Retrieving info");
  }
};
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top