Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>High performance loader - after examining the methods suggested here, I used <a href="http://negativeprobability.blogspot.com/2011/08/lazy-loading-of-images-in-listview.html" rel="noreferrer">Ben's solution</a> with some changes - </p> <ol> <li><p>I realized that working with drawables is faster that with bitmaps so I uses drawables instead</p></li> <li><p>Using SoftReference is great, but it makes the cached image to be deleted too often, so I added a Linked list that holds images references, preventing from the image to be deleted, until it reached a predefined size</p></li> <li><p>To open the InputStream I used java.net.URLConnection which allows me to use web cache (you need to set a response cache first, but that's another story)</p></li> </ol> <p>My code:</p> <pre><code>import java.util.Map; import java.util.HashMap; import java.util.LinkedList; import java.util.Collections; import java.util.WeakHashMap; import java.lang.ref.SoftReference; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import android.graphics.drawable.Drawable; import android.widget.ImageView; import android.os.Handler; import android.os.Message; import java.io.InputStream; import java.net.MalformedURLException; import java.io.IOException; import java.net.URL; import java.net.URLConnection; public class DrawableBackgroundDownloader { private final Map&lt;String, SoftReference&lt;Drawable&gt;&gt; mCache = new HashMap&lt;String, SoftReference&lt;Drawable&gt;&gt;(); private final LinkedList &lt;Drawable&gt; mChacheController = new LinkedList &lt;Drawable&gt; (); private ExecutorService mThreadPool; private final Map&lt;ImageView, String&gt; mImageViews = Collections.synchronizedMap(new WeakHashMap&lt;ImageView, String&gt;()); public static int MAX_CACHE_SIZE = 80; public int THREAD_POOL_SIZE = 3; /** * Constructor */ public DrawableBackgroundDownloader() { mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE); } /** * Clears all instance data and stops running threads */ public void Reset() { ExecutorService oldThreadPool = mThreadPool; mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE); oldThreadPool.shutdownNow(); mChacheController.clear(); mCache.clear(); mImageViews.clear(); } public void loadDrawable(final String url, final ImageView imageView,Drawable placeholder) { mImageViews.put(imageView, url); Drawable drawable = getDrawableFromCache(url); // check in UI thread, so no concurrency issues if (drawable != null) { //Log.d(null, "Item loaded from mCache: " + url); imageView.setImageDrawable(drawable); } else { imageView.setImageDrawable(placeholder); queueJob(url, imageView, placeholder); } } private Drawable getDrawableFromCache(String url) { if (mCache.containsKey(url)) { return mCache.get(url).get(); } return null; } private synchronized void putDrawableInCache(String url,Drawable drawable) { int chacheControllerSize = mChacheController.size(); if (chacheControllerSize &gt; MAX_CACHE_SIZE) mChacheController.subList(0, MAX_CACHE_SIZE/2).clear(); mChacheController.addLast(drawable); mCache.put(url, new SoftReference&lt;Drawable&gt;(drawable)); } private void queueJob(final String url, final ImageView imageView,final Drawable placeholder) { /* Create handler in UI thread. */ final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { String tag = mImageViews.get(imageView); if (tag != null &amp;&amp; tag.equals(url)) { if (imageView.isShown()) if (msg.obj != null) { imageView.setImageDrawable((Drawable) msg.obj); } else { imageView.setImageDrawable(placeholder); //Log.d(null, "fail " + url); } } } }; mThreadPool.submit(new Runnable() { @Override public void run() { final Drawable bmp = downloadDrawable(url); // if the view is not visible anymore, the image will be ready for next time in cache if (imageView.isShown()) { Message message = Message.obtain(); message.obj = bmp; //Log.d(null, "Item downloaded: " + url); handler.sendMessage(message); } } }); } private Drawable downloadDrawable(String url) { try { InputStream is = getInputStream(url); Drawable drawable = Drawable.createFromStream(is, url); putDrawableInCache(url,drawable); return drawable; } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } private InputStream getInputStream(String urlString) throws MalformedURLException, IOException { URL url = new URL(urlString); URLConnection connection; connection = url.openConnection(); connection.setUseCaches(true); connection.connect(); InputStream response = connection.getInputStream(); return response; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

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