So, you want to create another AsyncTask that sets the URL, downloads the image and populates some control. Usually I do something like this:
ImageView imageView = (ImageView)findById(R.id.blah); new ImageLoader( person.getImageUri(), imageView, 128, 128 ).execute();
ImageLoader will be another AsyncTask as follows:
public class ImageLoader extends AsyncTask<URI,Integer,BitmapDrawable> { private Uri imageUri; private ImageView imageView; private int preferredWidth = 80; private int preferredHeight = 80; public ImageLoader( URI uri, ImageView imageView, int scaleWidth, int scaleHeight ) { this.imageUri = uri; this.imageView = imageView; this.preferredWidth = scaleWidth; this.preferredHeight = scaleHeight; } public BitmapDrawable doInBackground(URI... params) { if( imageUri == null ) return null; String url = imageUri.toString(); if( url.length() == 0 ) return null; HttpGet httpGet = new HttpGet(url); DefaultHttpClient client = new DefaultHttpClient(); HttpResponse response = client.execute( httpGet ); InputStream is = new BufferedInputStream( response.getEntity().getContent() ); try { Bitmap bitmap = BitmapFactory.decodeStream(is); if( preferredWidth > 0 && preferredHeight > 0 && bitmap.getWidth() > preferredWidth && bitmap.getHeight() > preferredHeight ) { return Bitmap.createScaledBitmap(bitmap, preferredWidth, preferredHeight, false); } else { return bitmap; } } finally { is.close(); } } } public void onPostExecute( BitmapDrawable drawable ) { imageView.setImageBitmap( drawable ); } }
You can then disable this AsyncTask when the image is anchored in your ListView by creating your own ListAdapter subclass. So you have to go down with the SimpleAdapter, because it's not so simple. This has many advantages, so you only upload displayed images. This means that a very small amount is loaded from the total. Also, your user can see the data before downloading the image in order to quickly access the data. If you did this in your existing AsyncTask, you uploaded each image, and the user would have to wait for each of them to complete before the data was shown to the user. There is something that can be improved. One AsyncTask uses its own thread, so you will be launching many threads potentially (10 or more) at the same time. This can kill your server with many clients. You can centralize them using an ExecutorService (i.e. a thread pool), but you have to mess up with AsyncTask and implement your own tool to start a task from the user interface thread and publish the results to the user interface thread. Secondly, your images will be loaded every time the user scrolls. To do this, I implemented my own caching scheme based on the image URI, so I load one image only once and return it from the cache. This is too much code to post here, but it is an exercise for the reader.
Also note that I am not sending back to the UI thread in onPostExecute (). This is because AsyncTask does this for me, I do not need to do it again, as your code above shows. You should simply remove this extra runnable and embed the code in onPostExecute ().