2011-01-05 4 views
2

J'ai une application qui est l'interface utilisateur prend un peu de travail pour construire (doit traiter certaines choses). Donc, je construis l'interface utilisateur en utilisant un AsynchTask (il montre une boîte de dialogue de progression tout en effectuant un traitement en arrière-plan, puis la mise à jour de l'interface utilisateur). Je voudrais être en mesure d'appeler ce AsynchTask à partir de OnRestoreInstanceState(), afin que je puisse reconstruire l'interface utilisateur sur une rotation. Cependant, quand je l'appelle MyAsynchTask.execute() de la méthode onRestorInstanceState(), je reçois l'exception ci-dessous:Android: AsynchTask échoue lorsqu'il est appelé à partir de onRestoreInstanceState()

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) 

Répondre

3

Étape 1: Faites votre AsyncTask une classe interne statique ou une classe Java régulière complète.

Etape 2: Associez manuellement l'activité à laquelle la tâche doit travailler via un paramètre constructeur, contenu dans un membre de données de la tâche.

Étape # 3: Retourne l'objet tâche de onRetainNonConfigurationInstance()

Étape 4: Dans onCreate() de la nouvelle instance d'activité, obtenir l'objet tâche existante via getLastNonConfigurationInstance() et réassocier manuellement l'activité la tâche doit travailler avec par une méthode de setter.

Étape 4: Si nécessaire, modifiez onPostExecute() pour ne pas référencer l'activité.

Here is a sample project démontrant ce flux.

+0

Merci pour la réponse détaillée. J'ai implémenté l'exemple que vous avez donné, mais maintenant j'obtiens cette erreur quand j'essaye d'exécuter mon AsynchTask à partir de ma méthode onRestore: Causée par: java.lang.IllegalStateException: Impossible d'exécuter la tâche: la tâche a déjà été exécutée (une tâche peut être exécutée une seule fois) .... at android.os.AsyncTask.execute (AsyncTask.java:383) – ab11

+0

@ ab11: Vous ne pouvez pas ré-exécuter des tâches. Si vous avez exécuté la tâche dans l'ancienne activité, vous n'avez pas besoin de la ré-exécuter dans la nouvelle activité. – CommonsWare

+0

Ma tâche s'exécute pour traiter certaines données dans un objet (actuellement) non sérialisable, qui est ensuite utilisé pour créer l'interface utilisateur. Donc sur une rotation, cet objet est perdu (parce que je ne peux pas le sérialiser actuellement dans le paquet stocké), c'est pourquoi je veux ré-exécuter ma AsynchTask, pour le restaurer. Je peux simplement créer une nouvelle instance de mon AsynchTask (par opposition à l'utilisation d'une variable membre, comme dans votre exemple). Mais même si je le fais et le passe this.MyActivity en tant que paramètre de la construction, je reçois toujours l'exception originale "window has leaked". – ab11

Questions connexes