Je convertis mon code de l'utilisation Handler
en AsyncTask
. Ce dernier est excellent dans ce qu'il fait - les mises à jour asynchrones et la gestion des résultats dans le thread principal de l'interface utilisateur. Ce qui ne me semble pas clair, c'est comment gérer les exceptions si quelque chose se détraque AsyncTask#doInBackground
.
La façon dont je le fais est d'avoir un gestionnaire d'erreur et de lui envoyer des messages. Cela fonctionne bien, mais est-ce la «bonne» approche ou y a-t-il une meilleure alternative?
Je comprends également que si je définis le gestionnaire d'erreurs en tant que champ d'activité, il doit s'exécuter dans le thread d'interface utilisateur. Cependant, parfois (de manière très imprévisible) j'obtiendrai une exception indiquant que le code déclenché à partir de Handler#handleMessage
s'exécute sur le mauvais thread. Dois-je initialiser le gestionnaire d'erreurs à la Activity#onCreate
place? Le placement runOnUiThread
dans Handler#handleMessage
semble redondant mais il s'exécute de manière très fiable.
Réponses:
Je tiens le
Throwable
ouException
dans l'AsyncTask
instance elle-même, puis je fais quelque chose aveconPostExecute()
, donc ma gestion des erreurs a la possibilité d'afficher une boîte de dialogue à l'écran.la source
AsyncTask
suivant le modèle que je décris.Créez un objet AsyncResult (que vous pouvez également utiliser dans d'autres projets)
Renvoyez cet objet à partir de vos méthodes AsyncTask doInBackground et vérifiez-le dans postExecute. (Vous pouvez utiliser cette classe comme classe de base pour vos autres tâches asynchrones)
Vous trouverez ci-dessous une maquette d'une tâche qui obtient une réponse JSON du serveur Web.
la source
super()
dansAsyncTaskResult
lorsque la classe ne couvre rien?Lorsque je ressens le besoin de gérer
AsyncTask
correctement les exceptions , j'utilise ceci comme super classe:Comme d'habitude, vous remplacez
doInBackground
votre sous-classe pour effectuer un travail en arrière-plan, en lançant volontiers des exceptions si nécessaire. Vous êtes alors obligé de mettre en œuvreonPostExecute
(car c'est abstrait) et cela vous rappelle doucement de gérer tous les types deException
, qui sont passés en paramètre. Dans la plupart des cas, les exceptions conduisent à un type de sortie d'interface utilisateur, c'est donconPostExecute
un endroit parfait pour le faire.la source
params
avant, pour qu'il soit plus similaire à l'original et plus facile à migrer?new Task("Param").execute()
plusnew Task().execute("Param")
.Si vous souhaitez utiliser le framework RoboGuice qui vous apporte d'autres avantages, vous pouvez essayer le RoboAsyncTask qui a un Callback onException () supplémentaire. Fonctionne vraiment bien et je l'utilise. http://code.google.com/p/roboguice/wiki/RoboAsyncTask
la source
RoboGuice
toujours vivant? Semble n'a pas été mis à jour depuis 2012?J'ai créé ma propre sous-classe AsyncTask avec une interface qui définit les rappels pour le succès et l'échec. Donc, si une exception est levée dans votre AsyncTask, la fonction onFailure obtient l'exception, sinon le rappel onSuccess obtient votre résultat. Pourquoi Android n'a pas quelque chose de mieux disponible me dépasse.
la source
Une solution plus complète à Cagatay Kalan est présentée ci-dessous:
AsyncTaskResult
ExceptionHandlingAsyncTask
Exemple de tâche
la source
Ce cours simple peut vous aider
la source
Une autre façon qui ne dépend pas du partage de membres variables consiste à utiliser cancel.
Cela provient de la documentation Android:
Vous pouvez donc appeler cancel dans l'instruction catch et vous assurer que onPostExcute n'est jamais appelé, mais à la place onCancelled est appelé sur le thread d'interface utilisateur. Ainsi, vous pouvez afficher le message d'erreur.
la source
cancel(boolean)
résultant en un appel àonCancelled()
existait depuis le début, mais aonCancelled(Result)
été ajouté dans l'API 11 .En fait, AsyncTask utilise FutureTask & Executor, FutureTask prend en charge la chaîne d'exceptions Tout d'abord définissons une classe d'assistance
Deuxièmement, utilisons
la source
Personnellement, j'utiliserai cette approche. Vous pouvez simplement attraper les exceptions et imprimer la trace de la pile si vous avez besoin des informations.
faire en sorte que votre tâche en arrière-plan renvoie une valeur booléenne.
C'est comme ça:
la source
Une autre possibilité serait d'utiliser
Object
comme type de retour, et enonPostExecute()
contrôle pour le type d'objet. C'est court.la source
Si vous connaissez l'exception correcte, vous pouvez appeler le
par exemple:
et allez dans "onProgressUpdate" et faites ce qui suit
Cela ne sera utile que dans certains cas. Vous pouvez également conserver une
Global
Exception
variable et accéder à l'exception.la source