Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/43.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android自定义视图位图大小超出VM预算_Android_Out Of Memory - Fatal编程技术网

Android自定义视图位图大小超出VM预算

Android自定义视图位图大小超出VM预算,android,out-of-memory,Android,Out Of Memory,我正在制作一个自定义视图,它有两个元素:一个背景,由一个位图(如地图)和一个小资源图像(如图钉)组成,用于指示地图上的位置。在每个gps位置上更改“我的视图获取”的更新,并在新位置移动定位销 首先,它工作正常,过了一段时间,我出现了以下错误: 错误/AndroidRuntime(416): java.lang.OutOfMemoryError:位图 规模超过虚拟机预算 我想这与一直在重新绘制地图有关。也许你有什么办法帮我 public class MyMapView extends View {

我正在制作一个自定义视图,它有两个元素:一个背景,由一个位图(如地图)和一个小资源图像(如图钉)组成,用于指示地图上的位置。在每个gps位置上更改“我的视图获取”的更新,并在新位置移动定位销

首先,它工作正常,过了一段时间,我出现了以下错误:

错误/AndroidRuntime(416): java.lang.OutOfMemoryError:位图 规模超过虚拟机预算

我想这与一直在重新绘制地图有关。也许你有什么办法帮我

public class MyMapView extends View {

private int xPos = 0; 
private int yPos = 0;
private Bitmap trackMap;

private Paint backgroundPaint;
private Bitmap resizedBitmap;

private Bitmap position;
private Matrix positionMatrix;
private Paint positionPaint;
private int space=0;

public MyMapView(Context context) {
 super(context);
 init(context, null);
}

public MyMapView(Context context, AttributeSet attrs) {
 super(context, attrs);
 init(context, attrs);
}

public MyMapView(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 init(context, attrs);
}

private void init(final Context context, AttributeSet attrs) {
 backgroundPaint = new Paint();
 backgroundPaint.setFilterBitmap(true);

 position = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.position);
 positionMatrix = new Matrix();

 positionPaint = new Paint();
 positionPaint.setFilterBitmap(true);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
}

@Override
protected void onDraw(Canvas canvas) {

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

  if (trackMap!=null)
  {

    resizedBitmap = Bitmap.createScaledBitmap(trackMap, height, height, true);



    space = (width - resizedBitmap.getWidth())/2;
    canvas.drawBitmap(resizedBitmap, space, 0, backgroundPaint);
   }


     if (xPos != 0 && yPos !=0)
     {
      canvas.save(Canvas.MATRIX_SAVE_FLAG);

      canvas.translate(xPos+space-position.getWidth()/2, yPos-position.getHeight()/2);
      canvas.drawBitmap(position, positionMatrix, positionPaint);

      canvas.restore();
     }

}

 public void updatePosition(int xpos, int ypos, Bitmap trackImage)
 {
  xPos=xpos;
  yPos=ypos;
  trackMap = trackImage;
  invalidate();
 }
}
@费多:我试过这样的方法:

if (trackMap!=null)
  {
   if (resizedBitmap != null) {
    resizedBitmap.recycle();
     }


    resizedBitmap = Bitmap.createScaledBitmap(trackMap, height, height, true);



    space = (width - resizedBitmap.getWidth())/2;
    canvas.drawBitmap(resizedBitmap, space, 0, backgroundPaint);
   }

  }
@Override
protected void onDraw(Canvas canvas) {

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

     if (trackMapRef != null) {

         Bitmap resizedBitmap = Bitmap.createScaledBitmap(trackMapRef.get(), width, height, true);


         space = (width - resizedBitmap.getWidth()) / 2;
         canvas.drawBitmap(resizedBitmap, space, 0, backgroundPaintRef.get());
     }


     if (xPos != 0 && yPos != 0) {
         canvas.save(Canvas.MATRIX_SAVE_FLAG);

         positionRef = new WeakReference<Bitmap>(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.position));
         positionMatrixRef = new WeakReference<Matrix>(new Matrix());
         Paint posPaint = new Paint();
         posPaint.setFilterBitmap(true);
         positionPaintRef = new WeakReference<Paint>(posPaint);

         canvas.translate(xPos + space - positionRef.get().getWidth() / 2, yPos - positionRef.get().getHeight() / 2);
         canvas.drawBitmap(positionRef.get(), positionMatrixRef.get(), positionPaintRef.get());

         canvas.restore();
     }

}
但还是一样。每次GPS检测到位置改变时,我都从活动中调用updatePosition(..),因此经常调用onDraw get。图像贴图为400x400像素

11-13 20:29:42.121: ERROR/AndroidRuntime(213): Uncaught handler: thread main exiting due to uncaught exception
11-13 20:29:42.150: ERROR/AndroidRuntime(213): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.graphics.Bitmap.nativeCreate(Native Method)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.graphics.Bitmap.createBitmap(Bitmap.java:468)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.graphics.Bitmap.createBitmap(Bitmap.java:435)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:340)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at com.vorienteering.customcontrols.MyMapView.onDraw(MyMapView.java:71)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.View.draw(View.java:6274)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewGroup.drawChild(ViewGroup.java:1526)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewGroup.drawChild(ViewGroup.java:1524)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.View.draw(View.java:6277)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewGroup.drawChild(ViewGroup.java:1526)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.View.draw(View.java:6277)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewGroup.drawChild(ViewGroup.java:1526)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewGroup.drawChild(ViewGroup.java:1524)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.View.draw(View.java:6277)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.widget.FrameLayout.draw(FrameLayout.java:352)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1883)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewRoot.draw(ViewRoot.java:1332)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1097)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1613)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.os.Looper.loop(Looper.java:123)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at android.app.ActivityThread.main(ActivityThread.java:4203)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at java.lang.reflect.Method.invokeNative(Native Method)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at java.lang.reflect.Method.invoke(Method.java:521)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
11-13 20:29:42.150: ERROR/AndroidRuntime(213):     at dalvik.system.NativeStart.main(Native Method)
@Peter Knego我在你的回答中编辑过。它在找到positionRef和其他一些方面存在问题。我更新了如下代码:

if (trackMap!=null)
  {
   if (resizedBitmap != null) {
    resizedBitmap.recycle();
     }


    resizedBitmap = Bitmap.createScaledBitmap(trackMap, height, height, true);



    space = (width - resizedBitmap.getWidth())/2;
    canvas.drawBitmap(resizedBitmap, space, 0, backgroundPaint);
   }

  }
@Override
protected void onDraw(Canvas canvas) {

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

     if (trackMapRef != null) {

         Bitmap resizedBitmap = Bitmap.createScaledBitmap(trackMapRef.get(), width, height, true);


         space = (width - resizedBitmap.getWidth()) / 2;
         canvas.drawBitmap(resizedBitmap, space, 0, backgroundPaintRef.get());
     }


     if (xPos != 0 && yPos != 0) {
         canvas.save(Canvas.MATRIX_SAVE_FLAG);

         positionRef = new WeakReference<Bitmap>(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.position));
         positionMatrixRef = new WeakReference<Matrix>(new Matrix());
         Paint posPaint = new Paint();
         posPaint.setFilterBitmap(true);
         positionPaintRef = new WeakReference<Paint>(posPaint);

         canvas.translate(xPos + space - positionRef.get().getWidth() / 2, yPos - positionRef.get().getHeight() / 2);
         canvas.drawBitmap(positionRef.get(), positionMatrixRef.get(), positionPaintRef.get());

         canvas.restore();
     }

}
@覆盖
受保护的void onDraw(画布){
int width=getMeasuredWidth();
int height=getMeasuredHeight();
if(trackMapRef!=null){
Bitmap resizedBitmap=Bitmap.createScaledBitmap(trackMapRef.get(),宽度,高度,true);
空格=(width-resizedBitmap.getWidth())/2;
drawBitmap(resizedBitmap,空格,0,backgroundPaintRef.get());
}
如果(xPos!=0&&yPos!=0){
canvas.save(canvas.MATRIX\u save\u标志);
positionRef=新的WeakReference(BitmapFactory.decodeResource(getContext().getResources(),R.drawable.position));
positionMatrixRef=新的WeakReference(新矩阵());
Paint posPaint=新油漆();
posPaint.setFilterBitmap(true);
positionPaintRef=新WeakReference(posPaint);
translate(xPos+space-positionRef.get().getWidth()/2,yPos-positionRef.get().getHeight()/2);
drawBitmap(positionRef.get(),positionMatrixRef.get(),positionPaintRef.get());
canvas.restore();
}
}
现在它的工作时间稍微长一点。加倍时间。但仍然会出现内存不足错误。 非常感谢你的帮助

正如Fedor提到的,我在想,有没有一种方法可以让我只在创建时绘制地图图像,然后只在绘制时更新pin位置?这似乎是更方便的方法,因为重新绘制地图只使用资源,而且一直都是一样的


谢谢大家的帮助。这是唯一阻止我完成项目的事情。

你在泄漏内存。您是否尝试过调整BitMap.recycle()的大小


还有为什么你总是重画地图?也许你可以将地图作为静态图像,只重新绘制pin?

你正在泄漏内存。您是否尝试过调整BitMap.recycle()的大小


还有为什么你总是重画地图?也许您可以将贴图作为静态图像,并仅重新绘制pin?

避免保留对
可绘制对象的引用(位图)-删除位图类型的类字段

阅读如何阅读

编辑:

试试这个:

public class MyMapView extends View {

    private int xPos = 0;
    private int yPos = 0;
    private WeakReference<Bitmap> trackMapRef;

    private WeakReference<Paint> backgroundPaintRef;

    private WeakReference<Bitmap> positionRef;
    private WeakReference<Matrix> positionMatrixRef;
    private WeakReference<Paint> positionPaintRef;
    private int space = 0;

    public MyMapView(Context context) {
        super(context);
        init(context, null);
    }

    public MyMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public MyMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs);
    }

    private void init(final Context context, AttributeSet attrs) {
        Paint paint = new Paint();
        paint.setFilterBitmap(true);
        backgroundPaintRef = new WeakReference<Paint>(paint);

        positionRef = new WeakReference<Bitmap>(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.position));
        positionMatrixRef = new WeakReference<Matrix>(new Matrix());

        Paint posPaint = new Paint();
        posPaint.setFilterBitmap(true);
        positionPaintRef = new WeakReference<Paint>(posPaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
    }

    @Override
    protected void onDraw(Canvas canvas) {

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

        if (trackMapRef != null) {

            Bitmap resizedBitmap = Bitmap.createScaledBitmap(trackMapRef.get(), width, height, true);


            space = (width - resizedBitmap.getWidth()) / 2;
            canvas.drawBitmap(resizedBitmap, space, 0, backgroundPaintRef.get());
        }


        if (xPos != 0 && yPos != 0) {
            canvas.save(Canvas.MATRIX_SAVE_FLAG);

            canvas.translate(xPos + space - positionRef.get().getWidth() / 2, yPos - positionRef.get().getHeight() / 2);
            canvas.drawBitmap(positionRef.get(), positionMatrixRef.get(), positionPaintRef.get());

            canvas.restore();
        }

    }

    public void updatePosition(int xpos, int ypos, Bitmap trackImage) {
        xPos = xpos;
        yPos = ypos;
        trackMapRef = new WeakReference<Bitmap>(trackImage);
        invalidate();
    }
}
公共类MyMapView扩展视图{
私有int xPos=0;
私有int yPos=0;
私有WeakReference trackMapRef;
私人WeakReference backgroundPaintRef;
私有WeakReference positionRef;
私有WeakReference位置矩阵外部参照;
私人weakreferef;
私有int空间=0;
公共MyMapView(上下文){
超级(上下文);
init(上下文,null);
}
公共MyMapView(上下文、属性集属性){
超级(上下文,attrs);
init(上下文,attrs);
}
公共MyMapView(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
init(上下文,attrs);
}
私有void init(最终上下文,AttributeSet attrs){
油漆=新油漆();
paint.setFilterBitmap(真);
backgroundPaintRef=新WeakReference(油漆);
positionRef=新的WeakReference(BitmapFactory.decodeResource(getContext().getResources(),R.drawable.position));
positionMatrixRef=新的WeakReference(新矩阵());
Paint posPaint=新油漆();
posPaint.setFilterBitmap(true);
positionPaintRef=新WeakReference(posPaint);
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
设置测量尺寸(测量等级getSize(宽度测量等级),测量等级getSize(高度测量等级));
}
@凌驾
受保护的void onDraw(画布){
int width=getMeasuredWidth();
int height=getMeasuredHeight();
if(trackMapRef!=null){
Bitmap resizedBitmap=Bitmap.createScaledBitmap(trackMapRef.get(),宽度,高度,true);
空格=(width-resizedBitmap.getWidth())/2;
drawBitmap(resizedBitmap,空格,0,backgroundPaintRef.get());
}
如果(xPos!=0&&yPos!=0){
canvas.save(canvas.MATRIX\u save\u标志);
translate(xPos+space-positionRef.get().getWidth()/2,yPos-positionRef.get().getHeight()/2);
drawBitmap(positionRef.get(),positionMatrixRef.get(),positionPaintRef.get());
canvas.restore();
}
}
公共void更新位置(int xpos、int ypos、位图trackImage){
xPos=xPos;
yPos=yPos;
trackMapRef=新的WeakReference(trackImage);
使无效();
}
}

避免保留对
可绘制文件的引用(位图)-删除位图类型的类字段

阅读如何阅读

编辑:

试试这个:

public class MyMapView extends View {

    private int xPos = 0;
    private int yPos = 0;
    private WeakReference<Bitmap> trackMapRef;

    private WeakReference<Paint> backgroundPaintRef;

    private WeakReference<Bitmap> positionRef;
    private WeakReference<Matrix> positionMatrixRef;
    private WeakReference<Paint> positionPaintRef;
    private int space = 0;

    public MyMapView(Context context) {
        super(context);
        init(context, null);
    }

    public MyMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public MyMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs);
    }

    private void init(final Context context, AttributeSet attrs) {
        Paint paint = new Paint();
        paint.setFilterBitmap(true);
        backgroundPaintRef = new WeakReference<Paint>(paint);

        positionRef = new WeakReference<Bitmap>(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.position));
        positionMatrixRef = new WeakReference<Matrix>(new Matrix());

        Paint posPaint = new Paint();
        posPaint.setFilterBitmap(true);
        positionPaintRef = new WeakReference<Paint>(posPaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
    }

    @Override
    protected void onDraw(Canvas canvas) {

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

        if (trackMapRef != null) {

            Bitmap resizedBitmap = Bitmap.createScaledBitmap(trackMapRef.get(), width, height, true);


            space = (width - resizedBitmap.getWidth()) / 2;
            canvas.drawBitmap(resizedBitmap, space, 0, backgroundPaintRef.get());
        }


        if (xPos != 0 && yPos != 0) {
            canvas.save(Canvas.MATRIX_SAVE_FLAG);

            canvas.translate(xPos + space - positionRef.get().getWidth() / 2, yPos - positionRef.get().getHeight() / 2);
            canvas.drawBitmap(positionRef.get(), positionMatrixRef.get(), positionPaintRef.get());

            canvas.restore();
        }

    }

    public void updatePosition(int xpos, int ypos, Bitmap trackImage) {
        xPos = xpos;
        yPos = ypos;
        trackMapRef = new WeakReference<Bitmap>(trackImage);
        invalidate();
    }
}
公共类MyMapView扩展视图{
私有int xPos=0;
私有int yPos=0;
私有WeakReference trackMapRef;
私人WeakReference backgroundPaintRef;
私有WeakReference positionRef;
私有WeakReference位置矩阵外部参照;
私人weakreferef;
私有int空间=0;
公共MyMapV