2010-03-21 5 views
9

Ich fange an zu denken, dass ein ProgressDialog zu bekommen die AsyncTask zu arbeiten hat eine innere Klasse innerhalb einer Aktivitätsklasse sein. Wahr? [Bearbeitet viel später ... die Antwort ist falsch und ich bin mir nicht sicher, ob das ein Bug ist oder was. Ich benutze Android 1.5. Ich werde auf Dienstleistungen lesen.]ProgressDialog arbeiten nicht in externen AsyncTask

ich eine Aktivität haben, die eine Datenbank mit Informationen zu manipulieren, verwendet. Wenn die Datenbank gefüllt ist, ist alles in Ordnung. Wenn es nicht ausgefüllt ist, muss ich Informationen von einer Website herunterladen, die Datenbank auffüllen und dann auf die gefüllte Datenbank zugreifen, um die Ansichten in onCreate fertigzustellen.

Problem ist, ohne irgendwelche Mittel, um zu bestimmen, wenn der AsyncTask Thread die Datenbank beendet hat bevölkern, erhalte ich die folgende Force Close Fehlermeldung: Leider! Die Anwendung wurde unerwartet beendet. Ich klicke auf die Schaltfläche "Schließen", der Hintergrund-AsyncTask-Thread funktioniert weiterhin, die Datenbank wird aufgefüllt und alles funktioniert einwandfrei.

Ich muss diese Fehlermeldung loswerden und brauche Hilfe, wie dies zu tun ist. Hier einige Pseudo-Code:

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 einer separaten Datei:

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

Hier ist der Stack-Trace aus dem Emulator:

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

Was mache ich falsch?

Mr. Snowflake,

Versuchte:

@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 als Fehler gekennzeichnet ist: Kein umschließenden Instanz des Typs Aktivität ist zugänglich in Umfang

Ich denke ich müssen FillDB erweitert Aktivität dann erstellen Sie eine private Klasse innerhalb FillDB AsyncTask erweitern? Das wird nicht funktionieren. Keine Zusicherung, wenn die FillDB-Aktivität gestartet wird und startActivityForResult nicht verwendet werden kann, da nach Abschluss des Vorgangs kein Ergebnis von AsyncTask zurückgegeben wird.

Update: Erprobt das Erstellen einer privaten Klasse in der aufrufenden Klasse. Kann immer noch keinen ProgressDialog anzeigen. Einer der Fehler ist: Kann Fenster nicht hinzufügen - Token-Null ist nicht für eine Anwendung. Ich habe keine Ahnung, auf welchen Token verwiesen wird.

+0

Verwenden Sie 'adb logcat', DDMS oder die DDMS-Perspektive in Eclipse, um die Java-Stack-Ablaufverfolgung im Dialogfeld zum Schließen erzwingen anzuzeigen, da diese Stack-Ablaufverfolgung Ihnen mehr Informationen über Fehler geben soll. – CommonsWare

+0

CommonsWare - Ich weiß nicht genug über adb, um den Stack-Trace in /data/anr/traces.txt zu finden. Aber mit Blick auf das Logcat und DDMS in Eclipse scheint es, als ob ich eine nicht abgefangene Runtime-Ausnahme habe. java.lang.reflect.InvocationTarget Exception java.lang.Runtime Exception WindowMai versucht Fenster mit nicht-Anwendungs-Token WindowToken (43711b88 token = null) hinzuzufügen, abgebrochen wird. Ich sah nach, ob der Kontext null war und es scheint nicht zu sein: this.context zeigt: Kontext \t android.app.Application (id = 830060323048) – eric

+0

Was mit dem Dialog geschieht, wenn Sie zwischen ändern Landscape/Portrait-Modus, während die Aufgabe ausgeführt wird? Ist es sicher, den Dialog in Runable mit runOnUiThread (...) zu erstellen? –

Antwort

2

gab ich auf AsyncTask und verwendet, um einen Handler das Thema zu behandeln. Alles ist gut.

Nicht sicher, ob es ein Fehler in 1.5 mit AsyncTask oder etwas anderes ist, das ich nicht tat.

0

Versuchen

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

als runnable als Argument Activity.runOnUiThread läuft(). Benutzeroberflächenelemente sollten im UI-Thread erstellt und bearbeitet werden. Ich denke, das gilt auch für Dialog s.

[Bearbeiten] Code:

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

Herr Schneeflocke, (wie ich Kommentare forma so alles nicht zusammen laufen?) Ich habe versucht: Activity.runOnUiThread ((Runnable) progressDialog.show (Kontext, "Working ..", "Abrufen von Informationen"); Es sagt mir: Kann nicht eine statische Referenz auf die nicht-statische Methode RunOnUIThread (Runnable) vom Typ Activity. – eric

+0

Ich habe den Beitrag aktualisiert, hoffe, dass hilft. – MrSnowflake

+0

MrSnowflake - versucht, aber nicht gehen.Ich habe meinen Beitrag bearbeitet um deinen Code in meinem zu zeigen, danke. – eric

2

Haben Sie darüber nachgedacht, die onCreateDialog() -Methode überschreiben Ihre Dialoge zu implementieren? Es ist einfach, sie auf diese Weise zu erstellen und zu steuern, da Android die meiste Arbeit für Sie erledigt. Ich habe ein Beispiel unten genau das, was Sie versuchen zu tun.

http://pastie.org/880540

+0

Jason, Das hat es auch nicht gemacht. Vielleicht habe ich noch etwas anderes? Welche Android-Version verwendest du? – eric

0

Ich hatte das gleiche Problem wie OP für ziemlich lange mit einer öffentlichen (externen) AsyncTask. Bei der Untersuchung der Fehlermeldung "Versuch, ein Fenster mit einem Token ohne Anwendung hinzuzufügen" habe ich festgestellt, dass das Problem darin besteht, den Kontext festzulegen, der im Konstruktor der AsyncTask übergeben wird. Der Kontext, der übergeben werden soll, ist "this", nicht this.getApplicationContext() oder this.getBaseContext(). Das hat mein Problem gelöst.

Verwandte Themen