Bugfix de fluidité pour podcastscience
Le seul flux RSS pour lequel je comptais utiliser l'App fait terriblement ramer sa listview, au point de devenir inutilisable lorsqu'on veut un ancien épisode :
podcastscience.fm/feed
Je pensais que c'était un problème général, mais il semble que les autres flux ne soient pas aussi lents.
Problème constaté sur mes deux appareils : HTC Desire Z (Android 2.3.3, Snapdragon S2 800Mhz) et tablette Acer A210 (Android 4.1.1, Tegra 3)
Un autre flux testé (Radio01.net) laggue un peu sur Snapdragon S2, mais ça reste bien plus utilisable.
C'est nickel sur un Tegra3, par contre.

Pour tout ce qui est bug, utilises le bouton ‘Contact support’ afin d’ouvrir un ticket.
Mais comme j’ai expliqué hier il ne s’agit pas d’un bug, mais plutot de limites hardware
-
Pour info sur la dernière version de l'app (en cours de déploiement) j'ai remplacé le cache de Bitmap que j'utilisais (une HashMap de SoftReference) par un LruCache. Résultat la purge du cache est "davantage maitrisée" et cela semble fixer le problème sur mon HTC Desire. La JVM Dalvik ne semble pas gérer correctement les SoftReferences et les GC beaucoup trop rapidement.
Il me reste à sizer correctement le LruCache pour limiter les risques d'OOM tout en maintenant de bonnes perfs. -
Je veux bien répondre à tes messages mais essaie de tenir compte de mes réponses ;)
Je répète donc une dernière fois.
Dans un background thread, l'image est scalée puis sauvée dans un cache.
Elle est ensuite associé à une imageview pour chaque ligne de la listview via un setImageBitmap() et c'est cette méthode qui bloque le thread principal.
La mémoire du cache d'image est limitée et si l'OS a besoin de mémoire le cache est purgé ce qui peut provoquer un nouveau scaling de l'image, mais qui se fera encore dans un background thread. -
Adrien commented
Je ne crois pas, selon les logs que je vous ai montré, je suis certain que le scale se fait une fois par cellule, et sur le thread de l'UI :
Si le scale de l'image se faisait avant d'être passée à l'imageView et dans un thread séparé, l'appli aurait les mêmes performances quelle que soit la taille de la source.
Mais ce n'est pas le cas, on voit qu'une source de 2500x2500 fait lagguer la liste.Je ne vois que deux explications :
- Soit l'ImageView récupère (par inadvertance) l'image non-processée et doit la scaler au dernier moment, sur le thread de l'UI, ce qui bloque l'interface.
- Soit le background thread qui processe l'image avant de la passer à l'ImageView ne s'éxécute aps sur thread séparé, mais bien sur le thread de l'UI.
Un handler instancié sur le thread de l'UI, un runnable.run() au lieu d'un runnable.start()... Ce genre d'erreurs d'innatention est assez facile, et on en fera toujours. -
Non comme expliqué le resizing ne pose aucun problème car il est effectué dans un background thread. Mais comme c'est l'appel à setBitmapImage() qui pose problème le lag intervient à chaque ligne.
Comme indiqué précédemment j'utilise un cache, des viewHolders et un traitement dans un background thread...
Je ne reproduit le ralentissement que sur mon HTC desire. Aucun lag sur S3, N4 et N7. -
Adrien commented
Effectivement, le problème est là.
Utiliser le inSampleImageSize save effectivement beaucoup de mémoire, et est la solution suggérée par Google.
(http://developer.android.com/training/displaying-bitmaps/load-bitmap.html).Mais il existe plusieurs moyens à ma connaissance de résoudre ce problème :
Lorsque tu télécharges la vignette du podcast, tu la stockes dans le cache, pour ne pas avoir à le re-télécharger à chaque scroll de la view?
Ensuite tu passes l'image à l'image view de chaque cellule qui se charge de la redimmensionner...
C'est ce qui bloque l'UI pendant 3 à 4 secondes pour chaque cellule (sur un Galaxy S3).La meilleure des solutions est certainement de ne faire le downscale qu'une seule fois, et garder le bitmap à la bonne taille dans le cache. Lorsque tu passeras le thumnail à la bonne taille aux ImageView de chaque cellule, elle n'aura plus aucun travail à faire.
Le lourd travail est déporté du thread de l'UI, la listview sera infiniement plus fluide.
Après, si tu ne souhaite pas stocker un thumbnail dans le cache, tu peux seulement garder la bitmap scalée en mémoire :
Déplacer l'opération de downscale dans l'asynctask qui remplace l'image par défaut par la vraie miniature suffirait à ne pas bloquer l'UI.
La liste défilerait avec fluidité, et les miniatures apparaîtraient quleques secondes après, mais l'interface ne serait pas bloquée.Un recyclage des cellules affiné peut aussi empêcher de refaire sans cesse le scale :
Lors d'un scroll vers le bas, la cellule disparaîssant en haut possède la même image que celle apparaissant en bas.
Il est donc possible de réutiliser la vue sans avoir à recalculer quoi que ce soit (comme lorsqu'on la déplace simplement). -
Il ne s'agit pas du flux du podcast donc je n'utilisais pas le même flux.
Concernant le flux du blog, le problème vient de la vignette qui a une résolution de 2500*2500 (http://www.podcastscience.fm/wp-content/uploads/2012/08/PodcastScience_02_white_background_1400.png).
Malgré une très forte mise à l'échelle (inSampleSize = 16) le setBitmapImage() bloque le thread principal assez longtemps sur mon HTC desire. Aucun problème sur mon N7 et N4.
D'autres apps utiliseront peut être l'autre vignette référencée dans le RSS à savoir le gif (http://www.podcastscience.fm/wp-content/uploads/2010/07/PodcastScience144.gif), mais ce n'est pas mon cas.
Je ne peux donc rien faire contre cette limitation hardware -
Adrien commented
Désolé, mais je persiste :
J'ai testé l'application et ce feed précis sur quelques devices, et voilà mes observations.HTC desire Z - 2.3.3 - Snapdragon 800mhz - inutilisable.
Samsung Galaxy Tab - 2.2 - Exynos 3110 1Ghz - inutilisable
Kobo Arc - 4.0.4 - 2x 1.5ghz - saccade énormément, mais utilisable.
Acer Iconia Tab A210 - 4.1.1 - 4x 1.2Ghz - saccade beaucoup, un peu plus utilisable.
Proto de 10 pouces - 4.2.2 - Tegra4 (4+1x 1.9Ghz) - presque parfait, mais quelques lags quand même.J'ai testé sur 3 connexions Wifi différentes, et systématiquement laissé votre app comme la seule en cours d'éxécution.
Le processus était le même pour chaque test :
Une installation fraîche depuis Google Play, j'ajoute "http://www.podastscience.fm/feed" comme flux RSS, je clique dessus, et j'essaye de scroller la liste vers le bas...Le logcat m'affiche des pages de :
08-02 15:34:25.317: I/InputDispatcher(324): Window 'Window{41895800 com.bambuna.podcastaddict/com.bambuna.podcastaddict.activity.EpisodeListActivity paused=false}' spent 3145.3ms processing the last input event: MotionEvent(action=1, deviceId=1, source=0x00001002)
08-02 15:34:25.327: I/Choreographer(11848): Skipped 214 frames! The application may be doing too much work on its main thread.A deux reprises, j'ai vu l'image par défaut du flux RSS apparaître avant le logo de PodcastScience, et la liste était fluide.
Mais dès que le logo de PodcastScience se propageait, la liste se mettait à ralentir.
Il est évident qu'il ne s'agit pas d'un problème hardware. Je vous invite à essayer une réinstallation complète (en désinstallant l'ancienne version auparavent), et en faisant le même test que moi.
Je pense que l'image est une bonne piste. -
Je suis abonné à ce podcast depuis plus de 2 ans et je ne constate aucune ralentissement sur mon HTC desire qui est a peine plus performant que le S2 800MHz.
Quand au Tegra3 je n'ai jamais constaté de ralentissement sur ma N7 alors que je dois avoir plus de 300 flux et 15000 épisodes.
Aucun traitement autre que de l'affichage pur n'est effectué sur le thread principal.
Et oui je connais les outils de base d'Eclipse ;) -
Adrien commented
Il ne peut sagir d'une limitation du hardware : d'autres applis concurrentes parsent ce flux sans lagguer, sur le même hardware.
Pour un snapdragon à 800mhz, on peut peut-être se poser la question (bien que je peux trouver des listviews plus complexes et plus fluides sr le même appareil)
Mais un Tegra3 ne peut pas être le bottleneck pour faire défiler 5 images et 400 caractères.
Il y a clairement des tâches complexes qui s'éxecutent dans le thread de l'UI de votre application.Je dispose à mon travail de nombreux devices de tests. Si vous le souhaitez, je peux vous faire parvenir une petite vidéo de test sur une tablette prototype équipée d'un Tegra4 (T40S).
Cela dissipera tout doute sur une limitation hardware.Je suis désolé pour ce retour.
Je suis aussi développeur Android de métier, et je sais que c'est pénible de voir remonter ce genre de bugs.
Mais votre application semble prometteuse, et utilisée par beaucoup de personnes, c'est dommage d'y trouver de tels ralentissements.Elipse possède queques outils très pratiques pour trouver les responsables.
Avez-vous essayé d'afficher le Traceview sur la listview de ce flux ?