Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I came up with a solution that I call “BatchImageDownloader” that has served well. Here’s a quick summary of how it is used:</p> <ul> <li><p>Keep a global HashMap (ideally in your Application object) that serves as a cache of drawable objects</p></li> <li><p>In the getView() method of your List Adapter, use the drawable from the cache for populating the ImageView in your list item.</p></li> <li><p>Create an instance of BatchImageDownloader, passing in your ListView Adapter</p></li> <li><p>Call addUrl() for each image that needs to be fetched/displayed</p></li> <li><p>When done, call execute(). This fires an AsyncTask that fetches all images, and as each image is fetched and added to the cache, it refreshes your ListView (by calling notifyDataSetChanged())</p></li> </ul> <p>The approach has the following advantages:</p> <ul> <li>A single worker thread is used to fetch all images, rather than a separate thread for each image/view</li> <li>Once an image is fetched, all list items that use it are instantly updated</li> <li>The code does not access the Image View in your List Item directly – instead it triggers a listview refresh by calling notifyDataSetChanged() on your List Adapter, and the getView() implementation simply pulls the drawable from the cache and displays it. This avoids the problems associated with recycled View objects used in ListViews.</li> </ul> <p>Here is the source code of BatchImageDownloader:</p> <pre><code>package com.mobrite.androidutils; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.widget.BaseAdapter; public class BatchImageDownloader extends AsyncTask&lt;Void, Void, Void&gt; { List&lt;String&gt; imgUrls = new ArrayList&lt;String&gt;(); BaseAdapter adapter; HashMap&lt;String, Drawable&gt; imageCache; public BatchImageDownloader(BaseAdapter adapter, HashMap&lt;String, Drawable&gt; imageCache) { this.adapter = adapter; this.imageCache = imageCache; } public void addUrl(String url) { imgUrls.add(url); } @Override protected Void doInBackground(Void... params) { for (String url : imgUrls) { if (!imageCache.containsKey(url)) { Drawable bm = downloadImage(url); if (null != bm) { imageCache.put(url, bm); publishProgress(); } } } return null; } @Override protected void onProgressUpdate(Void... values) { adapter.notifyDataSetChanged(); } @Override protected void onPostExecute(Void result) { adapter.notifyDataSetChanged(); } public Drawable downloadImage(String url) { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpGet request = new HttpGet(url); try { HttpResponse response = httpClient.execute(request); InputStream stream = response.getEntity().getContent(); Drawable drawable = Drawable.createFromStream(stream, "src"); return drawable; } catch (ClientProtocolException e) { e.printStackTrace(); return null; } catch (IllegalStateException e) { e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } } } </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.
    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