Note that there are some explanatory texts on larger screens.

plurals
  1. POImageview gets set multiple time using AsyncTask in Android
    text
    copied!<p>I followed the procedure <a href="http://android-developers.blogspot.in/2010/07/multithreading-for-performance.html" rel="nofollow">here</a> and set up an easy AsyncTask Image downloader/loader for me. I call the download function from inside my GetView of the Adapter. Thus, everytime I scroll up or down, once the view goes out of screen, the images vanish only to be set again when I scroll back to that item. How do I stop this and, once I've all the images downloaded/cached, to set it. I don't want my ImageViews to be reset every single time. </p> <p>This is the ImageManager:</p> <pre><code>import java.io.File; import java.io.FileOutputStream; import java.net.URL; import java.util.HashMap; import java.util.Stack; import android.R; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.widget.ImageView; public class ImageManager { private HashMap&lt;String, Bitmap&gt; imageMap = new HashMap&lt;String, Bitmap&gt;(); private File cacheDir; public Thread imageLoaderThread = new Thread() ; public ImageQueue imageQueue = new ImageQueue(); public ImageManager(Context context) { // Make background thread low priority, to avoid affecting UI performance imageLoaderThread.setPriority(Thread.NORM_PRIORITY-1); // Find the dir to save cached images String sdState = android.os.Environment.getExternalStorageState(); if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) { File sdDir = android.os.Environment.getExternalStorageDirectory(); cacheDir = new File(sdDir,"data/codehenge"); } else cacheDir = context.getCacheDir(); if(!cacheDir.exists()) cacheDir.mkdirs(); } private void queueImage(String url, ImageView imageView) { // This ImageView might have been used for other images, so we clear // the queue of old tasks before starting. imageQueue.Clean(imageView); ImageRef p=new ImageRef(url, imageView); synchronized(imageQueue.imageRefs) { imageQueue.imageRefs.push(p); imageQueue.imageRefs.notifyAll(); } // Start thread if it's not started yet if(imageLoaderThread.getState() == Thread.State.NEW) imageLoaderThread.start(); } private class ImageRef { public String url; public ImageView imageView; public ImageRef(String u, ImageView i) { url=u; imageView=i; } } private class ImageQueue { private Stack&lt;ImageRef&gt; imageRefs = new Stack&lt;ImageRef&gt;(); //removes all instances of this ImageView public void Clean(ImageView view) { for(int i = 0 ;i &lt; imageRefs.size();) { if(imageRefs.get(i).imageView == view) imageRefs.remove(i); else ++i; } } } private class ImageQueueManager implements Runnable { @Override public void run() { try { while(true) { // Thread waits until there are images in the // queue to be retrieved if(imageQueue.imageRefs.size() == 0) { synchronized(imageQueue.imageRefs) { imageQueue.imageRefs.wait(); } } // When we have images to be loaded if(imageQueue.imageRefs.size() != 0) { ImageRef imageToLoad; synchronized(imageQueue.imageRefs) { imageToLoad = imageQueue.imageRefs.pop(); } Bitmap bmp = getBitmap(imageToLoad.url); imageMap.put(imageToLoad.url, bmp); Object tag = imageToLoad.imageView.getTag(); // Make sure we have the right view - thread safety defender if(tag != null &amp;&amp; ((String)tag).equals(imageToLoad.url)) { BitmapDisplayer bmpDisplayer = new BitmapDisplayer(bmp, imageToLoad.imageView); Activity a = (Activity)imageToLoad.imageView.getContext(); a.runOnUiThread(bmpDisplayer); } } if(Thread.interrupted()) break; } } catch (InterruptedException e) {} } private Bitmap getBitmap(String url) { String filename = String.valueOf(url.hashCode()); File f = new File(cacheDir, filename); // Is the bitmap in our cache? Bitmap bitmap = BitmapFactory.decodeFile(f.getPath()); if(bitmap != null) return bitmap; // Nope, have to download it try { bitmap = BitmapFactory.decodeStream(new URL(url).openConnection().getInputStream()); // save bitmap to cache for later writeFile(bitmap, f); return bitmap; } catch (Exception ex) { ex.printStackTrace(); return null; } } private void writeFile(Bitmap bmp, File f) { FileOutputStream out = null; try { out = new FileOutputStream(f); bmp.compress(Bitmap.CompressFormat.PNG, 80, out); } catch (Exception e) { e.printStackTrace(); } finally { try { if (out != null ) out.close(); } catch(Exception ex) {} } } } public void displayImage(String url, Activity activity, ImageView imageView) { if(imageMap.containsKey(url)) { Bitmap bitmapToShow = imageMap.get(url); if(bitmapToShow != null) { //&gt; Image was cached well imageView.setImageBitmap(bitmapToShow); return; } } //&gt; Image was cached failed else { imageView.setImageResource(R.drawable.btn_radio); queueImage(url,imageView); return; } } private class BitmapDisplayer implements Runnable { Bitmap bitmap; ImageView imageView; public BitmapDisplayer(Bitmap b, ImageView i) { bitmap=b; imageView=i; } public void run() { if(bitmap != null) imageView.setImageBitmap(bitmap); else imageView.setImageResource(R.drawable.spinner_background); } } } </code></pre> <p>My View:</p> <pre><code>if( v == null){ LayoutInflater li = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = li.inflate(R.layout.list_item,null); holder = new ViewHolder(); holder.name = (TextView)v.findViewById(R.id.name); holder.text = (TextView)v.findViewById(R.id.text); holder.displayPic = (ImageView)v.findViewById(R.id.DisplayPicture); v.setTag(holder); } else { holder = (ViewHolder)v.getTag(); obj = objs.get(position); if (obj != null) { holder.name.setText(obj.Name); holder.text.setText(""+obj.snippet); holder.displayPic.setTag(obj.ImageUrl); imageManager.displayImage(obj.ImageUrl, activity, holder.displayPic); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload