dafi dafi - 2 months ago 9
Android Question

How to have WebView performances while reading images into a GridView

I have a GridView filled with 50-100 images, images are loaded asynchronously starting from their urls.
I use the ArrayAdapter shown below, it sets a placeholder image then runs a thread to load the image.

The code works fine but it's very slooooow, so I would understand how a WebView is so fast?

A WebView can load an HTML page with dozen of images in just some second.
if I create an HTML page with my images urls (only

img
tags) it loads in few milliseconds.

How do I must write code to have performances similar to WebView component?

Just for completeness caching images is irrelevant in my case

Optimizing thread creation (generating 100 threads isn't the best practice) doesn't resolve the problem but obviously the time decreases of a bunch of seconds.

public class ImageAdapter extends ArrayAdapter<ImageInfo> {
private static final String POSITION = "position";
private static final String URL = "url";
private static final String BITMAP = "bitmap";

SparseArray<ImageView> views = new SparseArray<ImageView>();

public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(getContext());
imageView.setLayoutParams(new GridView.LayoutParams(75, 75));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(0, 0, 0, 0);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(android.R.drawable.ic_menu_gallery);

Bundle b = new Bundle();
b.putString(URL, getItem(position).thumbnailURL);
b.putInt(POSITION, position);
new LoadImage().execute(b);

views.put(position, imageView);
return imageView;
}

private class LoadImage extends AsyncTask<Bundle, Void, Bundle> {
protected Bundle doInBackground(Bundle... b) {
String url = b[0].getString(URL);

try {
b[0].putParcelable(BITMAP, ImageUtils.readImage(url));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return b[0];
}

protected void onPostExecute(Bundle result) {
ImageView view = views.get(result.getInt(POSITION));

view.setImageBitmap((Bitmap) result.getParcelable(BITMAP));
}
}
}


The ImageInfo class

public class ImageInfo {
public String thumbnailURL;
public String imageURL;
}

Answer Source

It could be slow due to a massive amount of GPU Overdraw your app may have. If you have an emulator or a device running Jellybean go into the developer settings and check GPU Overdraw then reopen your app. If it is mostly red, your problem may lay there, especially with a lot of sections to your gridview. If it is mostly red, I recommend reading this and fixing your overdraw problem: Romain Guy's Optimisation guide.