2 つのビットマップを描画する必要があるカスタム ビューがあります。1 つはマップのイメージを表す背景で、もう 1 つはキャンバスの上部/左側の位置に描画されるピンです。
両方の画像は onDraw で描画され、ビューを含むアクティビティのライブ中は同じままです。しばらくすると、
OutOfMemoryError: ビットマップ サイズが VM の予算を超えています
これは、リークがあり、ビットマップのガベージ コレクションが行われないことを意味します。以前も質問しましたが、状況が少し変わりました。使用したいビットマップを設定する 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() を呼び出します。それでもエラーが発生します。これを読んだことがありますが、自分のケースに適応させる方法がわかりません
私は他の解決策を受け入れます。マップ ビットマップのサイズを変更し (マイ アクティビティに含まれるレイアウトの高さに基づいて)、正しい場所に位置を描画できるようにする必要があることに注意してください。