在 Android 中的 draw/layout 操作错误期间避免对象分配

Avoid object allocations during draw/layout operations error in Android

我在 Android Studio 中遇到此错误:

Avoid object allocations during draw/layout operations

代码:

public class cizim extends View {

    Path path = new Path();
    Paint paint = new Paint();

    public cizim (Context c){
        super(c);
        paint.setColor(Color.BLACK);
        paint.setAntiAlias(true);

    }

    @Override
    protected void onDraw(Canvas canvas){
        canvas.setBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.foto));
        canvas.drawPath(path, paint);
        super.onDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        float x = event.getX();
        float y = event.getY();
        path.addCircle(x, y, 10, Path.Direction.CW);
        invalidate();
        return super.onTouchEvent(event);
    }

}

我收到此代码的错误:

canvas.setBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.foto));

我该如何解决这个问题?

我需要你的帮助。

绘制视图始终是一项繁重的任务,因为每当需要再次绘制视图时都会调用 onDraw 方法,因此想象一下该方法中的 allocating/creating 个新对象;这肯定会花费很多时间,并且会降低您的应用程序性能。

因此,与其在每次调用 onDraw 时都创建位图,不如在视图构造函数中只创建一次。

添加一个新的实例变量到你的 class:

public class cizim extends View {

    private Bitmap bitmap;

    ...
}

然后在您的构造函数中,按如下方式创建该对象:

public cizim(Context context) {
    super(context);
    paint.setColor(Color.BLACK);
    paint.setAntiAlias(true);
    bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.foto);
}

最后将您的 onDraw 方法修改为:

@Override
protected void onDraw(Canvas canvas){
    canvas.setBitmap(bitmap);
    canvas.drawPath(path, paint);
    super.onDraw(canvas);
}

编辑:

您的代码实际上存在另一个问题,在调用 canvas.setBitmap 时会导致 UnsupportedOperationException。如果你参考 documentation, setBitmap will change the bitmap the canvas will draw to. Since you need to draw the bitmap on the screen, you cannot use setBitmap here. So what you actually need is canvas.drawBitmap

将您的 onDraw 方法更改为:

@Override
protected void onDraw(Canvas canvas){
    canvas.drawBitmap(bitmap, 0, 0, paint);
    canvas.drawPath(path, paint);
    super.onDraw(canvas);
}