What if you have the listview load the images from a hashmap, and have a separate process fill the hashmap in the background?
On Jul 12, 3:47 pm, Evan Charlton <evancharl...@gmail.com> wrote: > Mark, > > Thanks for the reply! > > > -- If you scroll enough before the image is done loading, and the row is > > recycled first, you'll get weird results (image will keep flipping to > > different pictures as its various tasks complete) > > Even if I never scroll, the results are still jumbled and/or duplicated. > > > 1. Rather than tie the AsyncTask to a specific ImageView, I have the > > AsyncTask notify the ListView when an image load is complete, providing > > it the URL of the loaded image. The ListView, when it inflates/recycles > > rows, attaches the URL of the image that is supposed to be shown to each > > ImageView via the setTag() method. Then, when the AsyncTask says > > such-and-so URL is ready, the ListView walks the ImageViews and sees if > > any are showing that image, by comparing the passed-in URL to each > > ImageView's getTag(). If there's a match, ListView then loads the image > > out of the AsyncTask-managed cache into the ImageView. This way, I don't > > keep a strict tie between the AsyncTasks and the ImageViews. I suspect > > there's a better-performing solution than my current implementation, but > > it's at least tolerable for the moment. > > I'll code this up later and see if I have any problems. > > > 2. Rather than try to hack around the existing AsyncTask's limitations, > > I copied its source code (thank you, Android and Apache 2!) and made it > > use an unbounded LinkedBlockingQueue and use more than one thread to > > process it. That beats the heck out of trying to keep your own queue to > > feed into the AsyncTask class's static queue. > > Haha, yeah, that code could be cleaner, but it works pretty reliably, > so I'm going to avoid replacing it until it becomes the problem. > > Evan Charlton > > On Sun, Jul 12, 2009 at 6:29 AM, Mark Murphy<mmur...@commonsware.com> wrote: > > > Evan Charlton wrote: > >> I will be surprised if this hasn't been asked before, but I've been > >> Googling for days now and haven't found anything very helpful. My > >> problem is this: > > >> I'm trying to lazy-load images into a ListView--almost exactly how > >> Market does it, if you're familiar with that. It's not exactly like > >> Market because the images there comes in batches whereas mine are one > >> at a time, but I digress... > > >> I have the following adapter:http://paste2.org/p/318634 > >> This adapter lazy-loads pages and each row's corresponding image (if > >> applicable) and caches it to disk for faster loading next time. This > >> all works perfectly *except* when loading images over the network, > >> they come in on the wrong rows and are sometimes duplicated. I assume > >> that this has to do with the adapter reusing views, but I haven't been > >> able to stamp it out. > > > I suspect you are on the money with your assessment of the problem. > > > You pass in an ImageView to the AsyncTask and tell the task to replace > > the image in that ImageView. However: > > > -- Since it is asynchronous, for a bit, the ImageView will remain > > unchanged, which in the case of a recycled row will be whatever it was > > before > > > -- If you scroll enough before the image is done loading, and the row is > > recycled first, you'll get weird results (image will keep flipping to > > different pictures as its various tasks complete) > > > I just went through implementing something very similar. I'll eventually > > tease it out into something reusable and open source. Compared to the > > snippet of your implementation, here are two things I did differently: > > > 1. Rather than tie the AsyncTask to a specific ImageView, I have the > > AsyncTask notify the ListView when an image load is complete, providing > > it the URL of the loaded image. The ListView, when it inflates/recycles > > rows, attaches the URL of the image that is supposed to be shown to each > > ImageView via the setTag() method. Then, when the AsyncTask says > > such-and-so URL is ready, the ListView walks the ImageViews and sees if > > any are showing that image, by comparing the passed-in URL to each > > ImageView's getTag(). If there's a match, ListView then loads the image > > out of the AsyncTask-managed cache into the ImageView. This way, I don't > > keep a strict tie between the AsyncTasks and the ImageViews. I suspect > > there's a better-performing solution than my current implementation, but > > it's at least tolerable for the moment. > > > 2. Rather than try to hack around the existing AsyncTask's limitations, > > I copied its source code (thank you, Android and Apache 2!) and made it > > use an unbounded LinkedBlockingQueue and use more than one thread to > > process it. That beats the heck out of trying to keep your own queue to > > feed into the AsyncTask class's static queue. > > > -- > > Mark Murphy (a Commons Guy) > >http://commonsware.com|http://twitter.com/commonsguy > > > Android 1.5 Programming Books:http://commonsware.com/books.html --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~----------~----~----~----~------~----~------~--~---