我有一个自定义视图,需要绘制两个位图:一个是背景图片,代表地图的图像;另一个是指针,将被绘制在画布的左上角位置。
这两张图片都在 onDraw 方法中绘制,并且在包含该视图的活动期间保持不变。一段时间后,我会收到“OutOfMemoryError: bitmap size exceeds VM budget”错误。
这意味着我存在内存泄漏,并且位图没有被垃圾回收。我之前问过这个问题,但现在情况有些变化。我创建了一个 init 方法,在其中设置要使用的位图,但这仍然不是一个好的方法,错误会在稍后出现。
以下是代码:
public class MyMapView extends View {
private int xPos = 0;
private int yPos = 0;
private int space = 0;
private Bitmap resizedBitmap;
private Bitmap position;
private Bitmap mapBitmap;
public void setMapBitmap(Bitmap value) {
this.mapBitmap = value;
}
public MyMapView(Context context) {
super(context);
}
public MyMapView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyMapView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void init(final Context context) {
Paint paint = new Paint();
paint.setFilterBitmap(true);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
resizedBitmap = Bitmap.createScaledBitmap(mapBitmap, height, height, true);
position = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.position);
space = (width - resizedBitmap.getWidth()) / 2;
}
public void destroy()
{
resizedBitmap.recycle();
resizedBitmap=null;
position.recycle();
position=null;
mapBitmap.recycle();
mapBitmap=null;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
if (mapBitmap != null) {
canvas.drawBitmap(resizedBitmap, space, 0, null);
}
if (xPos != 0 && yPos != 0) {
canvas.translate(xPos + space - position.getWidth() / 2, yPos - position.getHeight() / 2);
canvas.drawBitmap(position, new Matrix(), new Paint());
}
}
public void updatePosition(int xpos, int ypos)
{
xPos = xpos;
yPos = ypos;
invalidate();
}
}
在包含视图的活动的onCreate方法中,我调用setMapBitmap()和init()方法。在此处,我知道哪个位图将被用作地图。在活动的onPause方法中,我调用了视图的destroy()方法。但是我仍然遇到错误。
我阅读了这个文章,但不知道如何将其应用到我的情况中。
我对任何其他解决方案都持开放态度。请注意,我需要调整地图位图的大小(基于包含它的布局的高度),并且仍然能够在正确的位置绘制位置。