我有一张地图应用。在我的代码中的某处,我将数据从数据库渲染到画布中。 我遇到了“内存不足”的异常,我无法弄清楚如何避免它。
这是相关方法。使用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);
}
我已经尝试过回收图片了,但是画布同意它无法使用回收的位图。
任何解决方案都会被贬低。
答案 0 :(得分:2)
我建议使用位图缓存。即使在预蜂窝上回收图像也需要时间来释放内存(位图数据存储在不由dalvik直接管理的本机内存中)。以下是位图缓存的示例。请根据您的需要进行调整。
/**
* @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();
}
}
}
答案 1 :(得分:1)
我已经尝试过回收图片了,但是画布同意它无法使用回收的位图。
我认为这个想法是你应该“回收”位图,然后把它放在地板上让垃圾收集器来处理。
以下是javadoc对recycle()
所说的内容:
“释放与此位图关联的本机对象,并清除对像素数据的引用。这不会同步释放像素数据;如果没有其他引用,它只是允许垃圾收集。位图已标记作为“死”,意味着如果调用getPixels()或setPixels(),它将抛出异常,并且不会绘制任何内容。此操作无法撤消,因此只有在确定没有进一步用途时才应调用它。 bitmap。这是一个高级调用,通常不需要调用,因为正常的GC进程会在没有更多对此位图的引用时释放这个内存。“。