tags:

views:

413

answers:

3

I am wondering if which of the two is better in loading images in a listview from web, is it by batch through some number of threads that are running simultaneously or one by one through thread queue?

I have noticed (but I don't know if that is really the implementation) from the youtube app that the images are loaded by batch and it is kinda fast. Even for not only loading images but also requesting some data from the web as well. Does anyone have an idea?

+1  A: 

The best way to have this kind of functionality is to have the images 'lazy load' in the list. If your list is of fixed size then run multiple threads (one for each visible list item), download the images and refresh the images in the list. In that mean time have some dummy image placed in the same location.

Have only a fixed number of image components for you list, preferably a few more then the total visible images at any point. Each time the list is scrolled, check whether the image corresponding to the that particular list item exists or not. If yes, display. If not, display the dummy image, run the thread to load the image in background and refresh the list image once download completes.

To further save the memory you can use 'SoftReferences' for the image components. This allows the garbage collector to take away the images that are not being shown on the screen at the moment.

Funkyidol
+4  A: 

"better" in which way? Performance wise? Developer-friendliness? Usability wise?

A couple fundamental things to consider:

  1. Creating threads is expensive. It's slow and each thread consumes system resources (of course). When creating a single thread for each download, use a managed capped thread pool.
  2. Don't load images if they're not visible to the user. What you should do is in getView() of your ListAdapter, check whether the image has already been loaded, and if not, re-use a thread from the thread pool to do the work.
  3. Be careful with AsyncTask. As far as I know, AsyncTask manages a fixed, application wide thread pool (I think it's capped to 5 threads), so if all these threads are busy loading images, any other task you perform through that class will block.
  4. Don't re-invent the wheel. Does the ImageLoader of Droid-Fu solve your problem? It also implements a cache, so images aren't downloaded twice.
Matthias
ImageLoader loads initially the images not in its correct position in a ListView but after a while it refreshes and then images are now on its right place. I just put this line of code into the getView() of my listview adapter `ImageLoader.start(imageUrl, new ImageLoaderHandler(imageView));` How am I gonna correct that? Can you help?
M.A. Cape
Update- I manage to fix it by setting tags in each view of the `ListView` and when the image is ready, I find the view by tag associated with the image and set the `ImageView` with that image. Your ImageLoader is sweet.... thanks a lot.
M.A. Cape
Yes, one has to be careful when re-using views and concurrency, since the view owner may change *before* a new image is posted back to the view. Using view tags is a very good solution to deal with this. Also, if this answers your question, please mark it as such :-)
Matthias
By the way, I sometimes got a warning02-15 13:02:27.839: WARN/nalizableReferenceQueue(1490): Could not load Finalizer in its own class loader. Loading Finalizer in the current class loader instead. As a result, you will not be able to garbage collect this class loader. To support reclaiming this class loader, either resolve the underlying issue, or move Google Collections to your system class path.How can I resolve this??
M.A. Cape
A: 

I tried to create a simple lazy list example that may be used as a reference, here it is http://stackoverflow.com/questions/541966/android-how-do-i-do-a-lazy-load-of-images-in-listview/3068012#3068012

Fedor