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?
I did same as the below code in the below url:
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;
}
................................................................................................... Here we have the code of ImageThreadLoaderClass:
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<String, SoftReference<Bitmap>> Cache;
Cache = new HashMap<String,SoftReference<Bitmap>>();
private final class QueueItem {
public URL url;
public ImageLoadedListener listener;
}
private final ArrayList<QueueItem> Queue = new ArrayList<QueueItem>();
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() > 0) {
final QueueItem item = Queue.remove(0);
// If in the cache, return that copy and be done
if( Cache.containsKey(item.url.toString()) && 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<Bitmap> 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<Bitmap>(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<Bitmap> 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;
}
}