Aller au contenu

AsyncTask multiples


pat

Recommended Posts

Salut voilà je me casse la tête depuis quelques jours pour réaliser un Usecase simple à expliquer:

Je veux mettre à jour une listview avec des objets sur un serveur, pour cela l'utilisateur click sur un bouton:

1) l'activity va interroger de manière asynchrone le serveur pour savoir cb il y a de nouveaux items

2) après lecture de la réponse, on lance des téléchargements asynchrones des items.

3) une fois TOUS les téléchargements effectués ont met à jour la listview.

Pour réaliser ca j'ai une première asynctask qui interroge le serveur et en retour appelle n fois une autre asynctask pour télécharger les n éléments. Je teste a la fin de cette seconde asynctask si on est sur le dernier dl pour mettre à jour ma listview. Ca marchouille plus ou moins.

Suis je tordu et y a t'il une facon plus clean pour réaliser ca? Car c'est assez penible en terme de code, et j'ai lu qu'il peut y avoir des limitations sur les asynctasks de par le SDK.

Lien vers le commentaire
Partager sur d’autres sites

Vous pourriez imaginer que le listener qui écoute vos AsyncTask sait combien il doit attendre de réponses, et dans ce cas lui faire déclencher une méthode lorsque vos n AsyncTask lui ont retourné un résultat.

Je ne pense pas que votre solution soit efficace, car le principe des AsyncTAsk c'est de ne pas être synchronisé ;)

Par conséquent rien ne dit que la dernière AsyncTask démarrée soit la dernière à retourner un résultat, et donc vous pourriez actualiser votre liste sans avoir obtenu tous les résultats.

Simon Daget.

Lien vers le commentaire
Partager sur d’autres sites

En fait c'est ce que je fais:

sur le onPostExecute j incremente un compteur que je test selon le nombre d'asynctask qui ont été lancé, donc je suis bien tjs sur la dernière.

Mon problème ne se situe pas vraiment la. mais plus sur le chainage d'asynctask que je trouve bizzare (mais je vois pas d autre solution) et des limitations de cette API.

Peut être que je devrais passer exclusivement par des Handler?

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

Une autre possibilité :

1. L'utilisateur clique sur ton bouton de mise à jour ;

2. Cela lance un AyncTask qui récupère le nombre de nouveaux items ;

3. L'Adapter est mis à jour avec ce nouveau nombre ;

4. L'Adapter est averti et rafraîchit ses items ;

5. Dans la méthode getView de l'Adapter tu lances pour chaque nouvel item un AsyncTask qui charge les données en arrière plan :

On retrouve ce type de traitement dans les galeries d'images, chaque miniature est chargée dans un Thread (AsyncTask) en arrière plan.

Avantage :

plus lisible

possibilité de mettre un "sablier" sur chaque item pour faire patienter l'utilisateur ;

Inconvénient :

un AsyncTask par item (quoique possible par lot)

peut-être plus difficile à implémenter

Bon courage,

ichpa

Lien vers le commentaire
Partager sur d’autres sites

en fait c'etait comme cela que je l'avais implémenté au debut ichpa mais j'avais 2 problèmes :

-les users se mette a naviguer dans la listview nimporte comment alors que les elements ne sont pas chargés, du coup le getview me balance enormement de demande de download...

par exemple la personne va scroller sur 10 elems non chargé = 10 requetes, puis ces elements passe hors vues alors qu'ils n ont pas été chargé puis la personne revient a la position de ces elems, cela va relancer des DL

-le fait de passer via un holder comme dans la gallery pour optimiser la mémoire fait que un element téléchargé se met a apparaitre nimporte où si l'utilisateur scroll trop vite, aléatoirement et retrouve sa bonne place dans la listview uniquement quand tous les éléments sont réccupérés et défilés.. (je sais c'est bizzarement expliqué mais en pratique le comportement est encore plus bizzare)

Bref au final j'ai décidé de ne mettre a jour ma listview uniquement apres le DL final et ne pas faire d appel asynchrone depuis le getview de l'adapter.

Lien vers le commentaire
Partager sur d’autres sites

C'est vrai que c'est plus simple d'afficher la liste une fois qu'elle est entièrement chargée.

Je ne pense pas que le système qui consiste à mettre un compteur qui s'incrémente dans le onPostExecute puisse fonctionner, puisque chaque incrémentation se déroule dans un thread différent. A moins qu'il ne s'agisse de données partagées bien sur.

La méthode que je vous proposais est un peu différente :

- Il s'agit d'un listener qui possède la liste de toutes les AsyncTask (n asyncTask pour n téléchargements).

- les AsyncTask appellent le listener dans la méthode onPostExecute, donc quand elle sont terminées.

Cette architecture permet au listener de savoir quelles sont les AsynTask qui lui ont répondu, et quelles sont celles dont il attend encore la réponse.

De cette façon, on peut imaginer un test à chaque traitement de retour, qui déclenche la méthode d'affichage de votre liste si l'ensemble des AyncTask sont terminées.

Je pense qu'il faut une AsyncTask par item de votre liste. Qu'il y en ai 2 ou 10 ne complique pas le code si celui-ci est bien structuré, en revanche le gain de temps peut être important si les requêtes sont traitées en parallèle.

Bonne chance,

Simon Daget

Lien vers le commentaire
Partager sur d’autres sites

Intéressant!

Au final j'ai refactoré les n Asynctask par n Handlers. Le compteur de test est bien global, donc pas de souci.

Ca m'a l'air bien plus stable. Je vais conserver cette approche.

Merci en tout cas pour avoir contribué.

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...