Anyone can help to how to handle bitmap exceeds VM buget error. Actually i had displayed more images in a listview. It works fine and throws bitmap error after repeated starting the activity, Any answers are appreciated heartedly.
4 Answers
These links might be useful to you.
http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html
Also this link, as it shows how anybody committs simple but drastic mistakes in implementing the list/grid which involves the loading of images.
How to solve the vm budget memory heap error in lazy loading bitmaps?
Also as you said that dis problem appears when you call your activity repeatedly, I suspect that you are loading images in threads which you are initializing in the getView method of your adapter.
This is something common that I have seens, people implement and then run into similar kinda issue.
If this is what happening in your code, you need to check it again, as this will lead to generation of threads for all the list rows whoes getView is called.
public enum BitmapLoading { INSTANCE;
private final Map<String, SoftReference<Bitmap>> cache;
private final ExecutorService pool;
private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
private Bitmap placeholder;
BitmapLoading() {
cache = new HashMap<String, SoftReference<Bitmap>>();
pool = Executors.newFixedThreadPool(5);
}
public void setPlaceholder(Bitmap bmp) {
try {
placeholder = bmp;
} catch (OutOfMemoryError e) {
placeholder.recycle();
bmp.recycle();
placeholder = null;
bmp = null;
}
}
public Bitmap getBitmapFromCache(String url) {
if (cache.containsKey(url)) {
return cache.get(url).get();
}
return null;
}
public void queueJob(final String url, final ImageView imageView,final int width, final int height) {
/* Create handler in UI thread. */
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
String tag = imageViews.get(imageView);
if (tag != null && tag.equals(url)) {
if (msg.obj != null) {
imageView.setImageBitmap((Bitmap) msg.obj);
} else {
imageView.setImageBitmap(placeholder);
Log.d(null, "fail " + url);
}
}
}
};
pool.submit(new Runnable() {
@Override
public void run() {
Bitmap bmp = null;
try{
bmp = downloadBitmap(url, width, height);
Message message = Message.obtain();
message.obj = bmp;
handler.sendMessage(message);
}catch (OutOfMemoryError e) {
bmp.recycle();
bmp = null;
}
}
});
}
public void loadBitmap(final String url, final ImageView imageView,final int width, final int height) {
imageViews.put(imageView, url);
Bitmap bitmap = null ;
try {
bitmap = getBitmapFromCache(url);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
imageView.setImageBitmap(placeholder);
queueJob(url, imageView, width, height);
}
} catch (OutOfMemoryError e) {
bitmap.recycle();
bitmap = null;
System.gc();
}
}
private Bitmap downloadBitmap(String url, int width, int height) {
Bitmap bitmap =null;
try {
bitmap = BitmapFactory.decodeStream((InputStream) new URL(url).getContent());
bitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);
cache.put(url, new SoftReference<Bitmap>(bitmap));
return bitmap;
}catch (OutOfMemoryError e) {
bitmap.recycle();
bitmap = null;
System.gc();
}
catch (MalformedURLException e) {
} catch (IOException e) {
}
return null;
}
}

- 408
- 1
- 5
- 12
You have to use lazy loading concept to solve this problem or you have to use soft reference concept with bitmap.

- 408
- 1
- 5
- 12
Actually there is a very good example of how to do Lazy Loading in listview in this project : Android Lazy Loading ListView.

- 14,365
- 41
- 114
- 185