gpt4 book ai didi

Android自定义 View 位图内存泄漏

转载 作者:IT老高 更新时间:2023-10-28 23:12:02 25 4
gpt4 key购买 nike

我有一个自定义 View ,我需要在其中绘制两个位图,一个是背景,代表 map 的图像,另一个是将绘制在 Canvas 顶部/左侧位置的图钉。

这两个图像都是在 onDraw 上绘制的,并且在包含该 View 的 Activity 的 Activity 期间保持不变。过了一会儿,我得到了一个

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();
}
}

我在包含 View 的 Activity 的 onCreate 上调用 setMapBitmap() 和 init()。在那里我知道什么位图将用作 map 。我调用 View 的destroy() 的 Activity 的onPause。我仍然得到错误。我读过这篇 this但我不知道如何适应我的情况

我愿意接受任何其他解决方案。请注意,我需要调整 map 位图的大小(基于 mai Activity 中包含它的布局的高度)并且仍然能够在正确的位置绘制位置。

最佳答案

你显然有内存泄漏。阅读如何 avoid memory leaks以及如何 find memory leaks .

这是一个重构为使用 Wea​​kReference 的代码:

public class MyMapView extends View {
private int xPos = 0;
private int yPos = 0;
private int space = 0;

private WeakReference<Bitmap> resizedBitmap;
private WeakReference<Bitmap> position;
private WeakReference<Bitmap> mapBitmap;

public void setMapBitmap(Bitmap value) {
this.mapBitmap = new WeakReference<Bitmap>(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(Bitmap mapBitmap) {
Paint paint = new Paint();
paint.setFilterBitmap(true);

int width = getMeasuredWidth();
int height = getMeasuredHeight();

resizedBitmap = new WeakReference<Bitmap>(Bitmap.createScaledBitmap(
mapBitmap, width, height, true));
position = new WeakReference(BitmapFactory.decodeResource(
getContext().getResources(), R.drawable.position));
space = (width - resizedBitmap.get().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.get(), space, 0, null);
}

if (xPos != 0 && yPos != 0) {
canvas.translate(xPos + space - position.get().getWidth() / 2,
yPos - position.get().getHeight() / 2);
canvas.drawBitmap(position.get(), new Matrix(), null);

}
}

public void updatePosition(int xpos, int ypos) {
xPos = xpos;
yPos = ypos;
invalidate();
}
}

关于Android自定义 View 位图内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4197794/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com