Issues while image downloading
<p>I have an app in which i am downloading images in a list activity. I am adding them to a queue in a thread and loading each and every image in athread. And deleting them using softreference. When iam loading the images for the first time they are gettting loaded. but when i scroll it from bottom to top some of that images are not getting loaded again. The progress bar is just rotating. Can any one of you help me in this?</p>

<p>I did same as the below code in the below url:</p>

<p><a href="http://ballardhack.wordpress.com/2010/04/10/loading-images-over-http-on-a-separate-thread-on-android/" rel="nofollow">http://ballardhack.wordpress.com/2010/04/10/loading-images-over-http-on-a-separate-thread-on-android/</a></p>

<p>Code:</p>

<pre><code>This line is there in itemlistadapter class.

private ImageThreadLoader imageLoader = new ImageThreadLoader();

This block of code is present in getview() method in a listactivity.

//Image downloading starts here
try 
{
holder.progress.setVisibility(View.VISIBLE);
Bitmap cachedImage = null;              


try 
{
cachedImage = imageLoader.loadImage(Item.ImageUrl, new ImageLoadedListener()
{
public void imageLoaded(Bitmap imageBitmap) 
{
holder.imgitem.setImageBitmap(imageBitmap);
notifyDataSetChanged();                
}
});
System.out.println("Print the cache image" + cachedImage);
}
catch (MalformedURLException e) 
{
Log.e("itemlistadapter", "Bad remote image URL: " + Item.ImageUrl, e);
}
if( cachedImage != null )
{
holder.imgitem.setImageBitmap(cachedImage);
holder.imgitem.setVisibility(View.VISIBLE);
holder.progress.setVisibility(View.GONE);
}
else
{                
int idNoImage = R.drawable.giftsuggestionsnoimage;
holder.imgitem.setBackgroundResource(idNoImage);
}   
}
catch(Exception e) 
{  
System.out.println("Exception in Downloading image : " + e.getMessage());       
}
return convertView;
}
</code></pre>

<p>...................................................................................................
    Here we have the code of ImageThreadLoaderClass:</p>

<pre><code>import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.Thread.State;
import java.lang.ref.SoftReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;  
import android.os.Handler;
import android.util.Log;

/**
* This is an object that can load images from a URL on a thread.
*
* @author Jeremy Wadsack
*/
public class ImageThreadLoader {
private static final String TAG = "ImageThreadLoader";

// Global cache of images.
// Using SoftReference to allow garbage collector to clean cache if needed
private final HashMap&lt;String, SoftReference&lt;Bitmap&gt;&gt; Cache; 
Cache = new HashMap&lt;String,SoftReference&lt;Bitmap&gt;&gt;();

private final class QueueItem {
public URL url;
public ImageLoadedListener listener;
}
private final ArrayList&lt;QueueItem&gt; Queue = new ArrayList&lt;QueueItem&gt;();

private final Handler handler = new Handler();  
// Assumes that this is started from the  main (UI) thread

private Thread thread;
private QueueRunner runner = new QueueRunner();;

/** Creates a new instance of the ImageThreadLoader */
public ImageThreadLoader() {
thread = new Thread(runner);
}

/**
* Defines an interface for a callback that will handle
* responses from the thread loader when an image is done
* being loaded.
*/

public interface ImageLoadedListener {
public void imageLoaded(Bitmap imageBitmap );
}

/**
* Provides a Runnable class to handle loading
* the image from the URL and settings the
* ImageView on the UI thread.
*/

private class QueueRunner implements Runnable 
{
public void run() {
synchronized(this) {
while(Queue.size() &gt; 0) {
final QueueItem item = Queue.remove(0);

// If in the cache, return that copy and be done

if( Cache.containsKey(item.url.toString()) &amp;&amp; Cache.get(item.url.toString()) != null) 
{
// Use a handler to get back onto the UI thread for the update
handler.post(new Runnable() {
public void run() {
if( item.listener != null ) {
// NB: There's a potential race condition here where the cache item could get
// garbage collected between when we post the runnable and it's executed.
//Ideally we would re-run the network load or something.

SoftReference&lt;Bitmap&gt; ref = Cache.get(item.url.toString());
if( ref != null ) 
{
                                                                    item.listener.imageLoaded(ref.get());
}
}
}
}); 
} 
else 
{
try
{
final Bitmap bmp = readBitmapFromNetwork(item.url);
if( bmp != null ) 
{
Cache.put(item.url.toString(), new SoftReference&lt;Bitmap&gt;(bmp));

//Use a handler to get back onto the UI thread for the update

handler.post(new Runnable() {
public void run() {
if( item.listener != null )
{
item.listener.imageLoaded(bmp);

}
}
});
}
}
catch(Exception e)
{System.out.println("Imagethreadloader:"+e.toString()); 
} 

}

}
}
}
}
/**
* Queues up a URI to load an image from for a given image view.
*
* @param uri    The URI source of the image
* @param callback   The listener class to call when the image is loaded
* @throws MalformedURLException If the provided uri cannot be parsed
* @return A Bitmap image if the image is in the cache, else null.
*/
public Bitmap loadImage( final String uri, final ImageLoadedListener listener)throws
MalformedURLException    
{
// If it's in the cache, just get it and quit it
if( Cache.containsKey(uri)) {
SoftReference&lt;Bitmap&gt; ref = Cache.get(uri);
if( ref != null ) {
return ref.get(); 
}
}
QueueItem item = new QueueItem(); 
item.url = new URL(uri);
item.listener = listener;
Queue.add(item);

// start the thread if needed
if( thread.getState() == State.NEW) {
thread.start();
} 
else if( thread.getState() == State.TERMINATED) 
{
thread = new Thread(runner);
thread.start();
}
return null;
}

/**
* Convenience method to retrieve a bitmap image from
* a URL over the network. The built-in methods do
* not seem to work, as they return a FileNotFound
* exception.
*
* Note that this does not perform any threading --
* it blocks the call while retrieving the data.
*
* @param url The URL to read the bitmap from.
* @return A Bitmap image or null if an error occurs.
*/
public static Bitmap readBitmapFromNetwork( URL url ) 
{
InputStream is = null;
BufferedInputStream bis = null;
Bitmap bmp = null;
try {
URLConnection conn = url.openConnection(); 
//conn.setUseCaches(true);
conn.connect();
//Object response = conn.getContent();
//if (response instanceof Bitmap) {
//bmp = (Bitmap)response;
//} 
BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inTempStorage = new byte[16*1024];
options.inSampleSize = 2; 
is = conn.getInputStream();
bis = new BufferedInputStream(is); 
try
{
bmp = BitmapFactory.decodeStream(bis,null,options);  
}           
catch(Exception e)
{
System.out.println("Imagethreadloader:"+e.toString());
}
} 
catch (MalformedURLException e) 
{
Log.e(TAG, "Bad ad URL", e); 
} 
catch (IOException e) 
{
Log.e(TAG, "Could not get remote ad image", e);
}
finally 
{
try {
if( is != null )
is.close();
if( bis != null )
bis.close();
} 
catch (IOException e) 
{
Log.w(TAG, "Error closing stream.");
}
}
return bmp;
}
}
</code></pre>
