2011-01-05 3 views
2

Ich habe eine App, die UI braucht ein wenig Arbeit zu bauen (muss einige Sachen verarbeiten). Also, ich baue die Benutzeroberfläche mit einer AsynchTask (es zeigt ein Fortschrittsdialog während der Hintergrundverarbeitung, dann wird die Benutzeroberfläche aktualisiert). Ich möchte in der Lage sein, diese AsynchTask von OnRestoreInstanceState() aufzurufen, damit ich die Benutzeroberfläche in einer Rotation neu erstellen kann. Allerdings, wenn ich MyAsynchTask.execute() aus der onRestorInstanceState() -Methode aufrufen, erhalte ich die folgende Ausnahme:Android: AsynchTask schlägt beim Aufruf von onRestoreInstanceState() fehl

01-05 12:28:45.194: ERROR/WindowManager(409): android.view.WindowLeaked: Activity com.MyActivity has leaked window [email protected] that was originally added here 
01-05 12:28:45.194: ERROR/WindowManager(409):  at android.view.ViewRoot.<init>(ViewRoot.java:247) 
01-05 12:28:45.194: ERROR/WindowManager(409):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148) 
01-05 12:28:45.194: ERROR/WindowManager(409):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 
01-05 12:28:45.194: ERROR/WindowManager(409):  at android.view.Window$LocalWindowManager.addView(Window.java:424) 
01-05 12:28:45.194: ERROR/WindowManager(409):  at android.app.Dialog.show(Dialog.java:241) 
01-05 12:28:45.194: ERROR/WindowManager(409):  at com.MyClass$MyAsynchTask.onPreExecute(MyClass.java:428) 

Antwort

3

Schritt # 1: Machen Sie Ihre AsyncTask eine statische innere Klasse oder eine regelmäßige vollständige Java-Klasse.

Schritt 2: Verknüpfen Sie manuell die Aktivität, mit der die Aufgabe arbeiten soll, über einen Konstruktorparameter, der in einem Datenelement der Aufgabe enthalten ist.

Schritt # 3: das Objekt Aufgabe Rückkehr von onRetainNonConfigurationInstance()

Schritt # 4: In onCreate() der neuen Aktivitätsinstanz, erhalten die bestehende Task-Objekt über getLastNonConfigurationInstance() und manuell die Aktivität erneut verknüpft die Aufgabe mit über arbeiten sollten eine Setter-Methode.

Schritt 4: Ändern Sie bei Bedarf onPostExecute(), um die Aktivität nicht zu referenzieren.

Here is a sample project diesen Fluss demonstrieren.

+0

Vielen Dank für die ausführliche Antwort. Ich habe das von Ihnen angegebene Beispiel implementiert, aber jetzt bekomme ich diesen Fehler, wenn ich versuche, meine AsynchTask über meine onRestore-Methode auszuführen: Verursacht von: java.lang.IllegalStateException: Task kann nicht ausgeführt werden: Der Task wurde bereits ausgeführt (eine Task kann ausgeführt werden) nur einmal) .... bei android.os.AsyncTask.execute (AsyncTask.java:383) – ab11

+0

@ ab11: Sie können Aufgaben nicht erneut ausführen. Wenn Sie die Aufgabe in der alten Aktivität ausgeführt haben, müssen Sie sie in der neuen Aktivität nicht erneut ausführen. – CommonsWare

+0

Meine Aufgabe wird ausgeführt, um einige Daten in ein (derzeit) unserialisierbares Objekt zu verarbeiten, das dann zum Erstellen der Benutzeroberfläche verwendet wird. Bei einer Rotation ist dieses Objekt also verloren (weil ich es momentan nicht in das gespeicherte Bündel serialisieren kann). Deshalb möchte ich meine AsynchTask erneut ausführen, um sie wiederherzustellen. Ich kann einfach eine neue Instanz meiner AsynchTask erstellen (im Gegensatz zur Verwendung einer Mitgliedsvariablen wie in Ihrem Beispiel). Aber selbst wenn ich das tue und es ihm übergebe. MeineAktivität als ein Parameter der Konstruktion, bekomme ich immer noch die ursprüngliche "window leaked" Ausnahme. – ab11