Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: What is the fastest way to load several bitmaps/thumbs via http?

I need to know : What is the fastest way to download several thumbs in a row, lets say 10 images. It seems like the built-in browser does this in a very clever way.

I have Google'd and found that most developers are using the HttpUrlConnection class to download a jpeg to display it in a ImageView, inside an ListAdapter etc.

Some developers implements the download by using DefaultHttpClient class as it has better support for timeouts etc. In fact Google recommends to use the Apache Http client, and not the native Java HttpUrlConnection. That said, both startegies mentioned works fine, but thay are very slow compared to how the build in browser on my HTC desire download thumbnails. The built in browser seems to download images about 5x-10x faster then when try to download the same bitmaps with my own code. And yes, I always do the download/http work on a separate worker thread (not GUI thread).

Do anybody know how the built-in browser is downloading thumbs, or at least what is the fastest way to download several images from a server ?

I have tried using this code:

DefaultHttpClient client = new DefaultHttpClient();
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParameters, SO_TIMEOUT);      
client.setParams(httpParameters);
client.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
    @Override
    public long getKeepAliveDuration(HttpResponse response, HttpContext context)
    {
        return 5000;
    }
});

Now, i use this connection to fetch several bitmaps / thumbs in a for-loop:

public static Bitmap downloadBitmap(String url, DefaultHttpClient client){

  HttpResponse response = null;
  HttpGet get = new HttpGet(url);
  try {
      response = client.execute(get);
      return BitmapFactory.decodeStream(response.getEntity().getContent());
  } 
  catch (ClientProtocolException e1) {
      e1.printStackTrace();
  }
  catch (IllegalStateException e){
      e.printStackTrace();
  } 
  catch (IOException e1) {
      e1.printStackTrace();
  }

  return null;
}

I created a testpage.html with 10 bitmaps and loaded it with the built-in browser. The browser renders the page with all the thumbs within 1 seconds. And I'm sure they are not cached in the browser, as i randomize the 10 images for every page-refresh.

When i try to make a simple activity that downloads and displays the same thumbs, its a lot slower.

I hope the Google Android Team picks up this and includes it in one of their video speaks on the next developer conference.

They should define a best-practise for this, as it seems that every developer tries to solve this "download-bitmap" use-case their own way, when we in fact are all trying to do the same thing.

I have also tested using the same DefaultHttpClient object to fetch several images by calling execute() with diffrent urls (HttpGet objects), but its still far from the speed to the built-in browser. I see that my requests has sat the connection keep-alive flag, but it does not seem to make any difference.

like image 618
Vidar Vestnes Avatar asked Dec 14 '10 15:12

Vidar Vestnes


2 Answers

There are two reasons why the built-in browser is faster as your code:

  1. The browser is mainly implemented in native code (e.g. WebKit)
  2. Multiple downloads are performed simultaneously (multiple threads)
like image 144
Robert Avatar answered Nov 15 '22 01:11

Robert


I'd use threads to download multiple images at once. This should help put your code on par with the browser.

like image 33
Navaar Avatar answered Nov 14 '22 23:11

Navaar