I have an map app. Somewhere in my code I am rendering data from database into canvas. I ran into "out of memory" exception and I cant figure out how to avoid it.
Here is the relevant method. I get exception when creating bitmap with bitmapfactory.
private static void _renderImage(Canvas g, Point[] points, RImageData imageData,
RMapView mapView) {
Bitmap image = (Bitmap)imageData.image;
Paint paint = new Paint();
if(image == null) {
image = BitmapFactory.decodeByteArray(imageData.getImageBytes(), 0,
imageData.getImageBytes().length);
imageData.image = image;
}
g.drawBitmap(image, points[0].x, points[0].y, paint);
}
I have tried recycling the image, but then the canvas coplains it cant work with recycled bitmaps.
Any solution would be much apreciated.
I would suggest having a bitmap cache. Even recycling images on pre-honeycomb takes time to free memory (Bitmap data is stored in native memory that is not directly managed by dalvik). Here is a sample of a bitmap cache. Please adjust it to your needs.
/**
* @author audrius Bitmap cache
*/
private static class BitmapCache {
//private static final String TAG = "BitmapCache";
private final int mCacheSize;
private final String mBitmapLocation;
private LinkedHashMap<String, Bitmap> mBitmapCache;
/**
* Constructor
*
* @param cacheSize
* Cache size in element count (e.g. 8 = at most 8 Bitmaps in
* cache)
* @param bitmapLocation
* Physical root path to bitmap location
*/
public BitmapCache(int cacheSize, String bitmapLocation) {
mCacheSize = cacheSize;
mBitmapLocation = bitmapLocation;
mBitmapCache = new LinkedHashMap<String, Bitmap>(mCacheSize + 1) {
private static final long serialVersionUID = -4156123801558395154L;
@Override
protected boolean removeEldestEntry(
java.util.Map.Entry<String, Bitmap> eldest) {
return size() > mCacheSize;
};
@Override
public Bitmap remove(Object key) {
Bitmap bmp = super.get(key);
// make sure to release resources as soon as possible
bmp.recycle();
return super.remove(key);
}
};
}
/**
* Returns Bitmap (either from cache or physical location)
*
* @param bitmapFilename
* @return
*/
public Bitmap getBitmap(String bitmapFilename) {
Bitmap ret = mBitmapCache.get(bitmapFilename);
//Log.v(TAG, "getBitmap : " + bitmapFilename);
if (ret == null) {
//Log.v(TAG, "Bitmap not cached, reading location : " + mBitmapLocation);
ret = BitmapFactory.decodeFile(new File(mBitmapLocation, bitmapFilename).getAbsolutePath());
mBitmapCache.put(bitmapFilename, ret);
}
return ret;
}
/**
* Clears bitmap cache
*/
public void clear() {
if (mBitmapCache != null) {
for (Bitmap bitmap : mBitmapCache.values()) {
if (bitmap != null) bitmap.recycle();
}
mBitmapCache.clear();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With