英文:
Avoid object allocations during draw/layout operations error in Android
问题
在Android Studio中,我遇到了以下错误:
> 在绘制/布局操作期间避免对象分配
代码如下:
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));
您该如何解决这个问题呢?我需要您的帮助。
英文:
I got this error in Android Studio:
> Avoid object allocations during draw/layout operations
Code:
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);
}
}
I got the error with this code:
canvas.setBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.foto));
How can I resolve this problem?
I need your help.
答案1
得分: 1
在onDraw
方法中绘制视图始终是一个繁重的任务,因为每当视图需要重新绘制时,都会调用onDraw
方法,因此想象一下在该方法中分配/创建新对象;这肯定会花费很多时间,并降低应用程序的性能。
因此,不要在每次调用onDraw
时都创建位图,而是在视图构造函数中仅创建一次。
在类中添加一个新的实例变量:
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.drawBitmap(bitmap, 0, 0, paint);
canvas.drawPath(path, paint);
super.onDraw(canvas);
}
编辑:
实际上,您的代码还存在另一个问题,调用canvas.setBitmap
时将导致UnsupportedOperationException
。如果参考文档,setBitmap
会更改画布绘制的位图。由于您需要在屏幕上绘制位图,因此在这里不能使用setBitmap
。您实际上需要的是canvas.drawBitmap。
将您的onDraw
方法更改为:
@Override
protected void onDraw(Canvas canvas){
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.drawPath(path, paint);
super.onDraw(canvas);
}
英文:
Drawing a view is always a heavy task because onDraw
method is invoked whenever the view needs to be drawn again, so imagine allocating/creating new objects in that method; it will certainly take a lot of time and will decrease your app performance.
So instead of creating your bitmap every time onDraw
is called, create it only once in your view constructor.
Add a new instance variable to your class:
public class cizim extends View {
private Bitmap bitmap;
...
}
Then in your constructor, create that object as follows:
public cizim(Context context) {
super(context);
paint.setColor(Color.BLACK);
paint.setAntiAlias(true);
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.foto);
}
Finally modify your onDraw
method to:
@Override
protected void onDraw(Canvas canvas){
canvas.setBitmap(bitmap);
canvas.drawPath(path, paint);
super.onDraw(canvas);
}
Edit:
There is actually another issue with your code that will result in UnsupportedOperationException
when calling canvas.setBitmap
. If you refer to the 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
Change your onDraw
method to:
@Override
protected void onDraw(Canvas canvas){
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.drawPath(path, paint);
super.onDraw(canvas);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论