刚开始使用 Android、canvas 和作品。我有可以在图形对象上绘制形状的现有 Java 代码。我正在尝试在带有 Canvas 的 Android 应用程序中使用该代码。基本上,我试图避免重构我的所有 Java 代码以显式使用 Canvas。所以我正在制作我自己的“图形”对象。它应该做的就是调用适当的 Canvas 方法来绘制指定的形状。
我在这里阅读了多篇关于无法在onDraw()
方法之外使用画布对象的帖子。据我了解,您不能将画布对象传递给不同的类并期望它正常工作。但我也没有完全理解这一切是如何运作的。
应用程序在 drawOval 方法的 Graphics 类中崩溃。我已经阅读了关于所有这些的日志,但我还没有找到一个很好的答案来说明为什么这特别不起作用。我一直无法找到一种以 Java 友好的方式(又名堆栈跟踪)获取崩溃日志的方法。它只是抛出Fatal signal 11 (SIGSEGV), code 1, fault addr 0x130 in tid 1520
.
谢谢!如果需要更多详细信息,请告诉我。这是我的代码:
MainActivity
public class MainActivity extends AppCompatActivity {
MyCanvas canvas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
canvas = new MyCanvas(this);
setContentView(canvas);
}
}
MyCanvas View
public class MyCanvas extends View {
Graphics graphics;
List<Shape> shapes;
public MyCanvas(Context context) {
super(context);
graphics = new Graphics();
shapes = new ArrayList<>();
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
graphics.setCanvas(canvas); //Sets the canvas object in the graphics class
for (Shape shape : shapes) {
try { //this is in a try/catch block for custom exception handling
//This just calls the specific shapes render method,
//in this case, a circle from the makeShape Method
//The graphics object then calls the specific shape to
//render on the canvas
shape.render(graphics, 0, 0);
} catch (ShapeException e) {
e.printStackTrace();
}
}
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int x = (int) event.getX();
int y = (int) event.getY();
try { //this is in a try/catch block for custom exception handling
makeShape(x, y);
} catch (ShapeException e) {
e.printStackTrace();
}
invalidate();
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: {
break;
}
}
invalidate();
return true;
}
public void makeShape(int x, int y) throws ShapeException{
Point p = new Point(x, y);
Shape shape = new Circle(p, 50, 50);
shapes.add(shape);
}
}
Graphics
public class Graphics {
private Canvas canvas = null;
public Graphics() {
}
public void setCanvas(Canvas canvas) {
if (this.canvas == null) {
this.canvas = canvas;
}
}
public void drawOval(int x, int y, int width, int height) {
Paint paint1 = new Paint();
paint.setColor(Color.BLACK);
canvas.drawCircle(500, 500, 50, paint1); //App crashes here
}
}
您对能够将 a 传递Canvas
给不同的类有轻微的误解。这绝对没有错。将画布传递给类方法实际上与将其传递给常规函数相同。即使将Canvas
引用存储在成员变量中也不会造成任何伤害。
但是,上述内容仅适用于Canvas
不能在draw()
/onDraw()
方法的范围之外使用的理解。也就是说,任何使用 的方法都Canvas
必须从 内部调用onDraw()
,或者由 调用的函数onDraw()
等。
这是因为Canvas
紧接在 之前(由框架)初始化onDraw()
,以便为当前的绘图操作做准备。您可能希望将其视为Canvas
使用 a 进行初始化Bitmap
,它将用作此特定屏幕帧的绘图输出表面(这与事实相去甚远)。一旦onDraw()
返回,框架假定您的代码将不再使用它,并且它可以提交输出表面Bitmap
/等。到屏幕合成器进行渲染,而无需担心进一步更改。
而且,您的方法是一种很好的方法,它是一种用于调整现有代码以使用新颖图形对象的技术。
因此,为了解决崩溃问题:当您不(直接)处理本机/JNI 例程时,在正常的 Android 开发中永远不会发生 SIGSEGV。但是,我发现如果Canvas
对象发生变化,您不会更新它。这可能会导致崩溃(在本机代码中,这就是您没有获得 Java 堆栈跟踪的原因)。Canvas
在给你一个新的之后,你用了一个旧的。删除条件if (this.canvas == null)
,你应该没问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句