Dans mon activité, j'utilise une classe qui s'étend d'AsyncTask et un paramètre qui est une instance de cette AsyncTask. Quand j'appelle, mInstanceOfAT.execute("")
tout va bien. Mais l'application plante lorsque j'appuie sur un bouton de mise à jour qui appelle à nouveau AsyncTask (au cas où le travail réseau ne fonctionnerait pas). Cause apparaît alors une exception qui dit
Impossible d'exécuter la tâche: la tâche a déjà été exécutée (une tâche ne peut être exécutée qu'une seule fois)
J'ai essayé d'appeler cancel (true) pour l'instance de l'Asyctask, mais cela ne fonctionne pas non plus. La seule solution à ce jour est de créer de nouvelles instances de l'Asyntask. Est-ce la bonne manière?
Merci.
la source
Les raisons pour lesquelles les instances d'ASyncTask fire-and-forget sont assez bien détaillées dans la réponse de Steve Prentice - Cependant, même si vous êtes limité sur le nombre de fois que vous exécutez une ASyncTask, vous êtes libre de faire ce que vous voulez pendant que le thread est en cours d'exécution. .
Placez votre code exécutable dans une boucle dans doInBackground () et utilisez un verrou simultané pour déclencher chaque exécution. Vous pouvez récupérer les résultats à l'aide de publishProgress () / onProgressUpdate () .
Exemple:
Bien sûr, cela est légèrement plus compliqué que l'utilisation traditionnelle d'ASyncTask, et vous abandonnez l'utilisation de publishProgress () pour les rapports d'avancement réels. Mais si la mémoire est votre préoccupation, cette approche garantira qu'une seule ASyncTask reste dans le tas au moment de l'exécution.
la source
IllegalMonitorStateException
enrunAgain
(appelé paronProgressUpdate
) voir cette réponse: stackoverflow.com/a/42646476/2711811 . Cela suggère (et a fonctionné pour moi) que lessignal()
besoins d'être entourés d'unlock
/unlock
. Cela peut avoir à voir avec le moment de l'publishProgress
appelonProgressUpdate
.J'ai eu le même problème. Dans mon cas, j'ai une tâche que je veux faire dans
onCreate()
et dansonResume(
). J'ai donc rendu mon Asynctask statique et j'en ai récupéré l'instance. Maintenant, nous avons toujours le même problème.Donc, ce que j'ai fait dans onPostExecute () est le suivant:
En gardant à l'esprit que je vérifie dans la méthode statique getInstance que mon instance n'est pas nulle, sinon je la crée:
La méthode dans postExecute videra l'instance et la recréera. Bien sûr, cela peut être fait en dehors de la classe.
la source
J'ai rendu mes tâches de rotation statiques, ce qui m'a ensuite aidé à les attacher, les détacher et les rattacher aux threads de l'interface utilisateur lors des changements de rotation. Mais pour revenir à votre question, je crée un indicateur pour voir si le fil est en cours d'exécution. Lorsque vous souhaitez redémarrer le thread, je vérifie si la tâche de rotation est en cours d'exécution si c'est le cas, je porte un avertissement. Si ce n'est pas le cas, je le rends nul, puis j'en crée un nouveau, qui contournera l'erreur que vous voyez. De plus, une fois terminé, j'annule la tâche de rotation terminée afin qu'elle soit prête à recommencer.
la source
Oui c'est vrai, le doc dit qu'on ne peut exécuter qu'une seule Asyntask.
Chaque fois que vous avez besoin de l'utiliser, vous devez créer une instance:
la source