Java 在不同类中使用Android画布,调试崩溃错误
从Android、canvas和作品开始。我有可以在图形对象上绘制形状的现有Java代码。我正试图在一个带有Canvas的Android应用程序中使用该代码。基本上,我试图避免重构所有Java代码以显式使用Canvas。所以我正在制作我自己的“图形”对象。它所要做的就是调用适当的Canvas方法来绘制指定的形状 我在这里读过多篇关于不能在Java 在不同类中使用Android画布,调试崩溃错误,java,android,canvas,Java,Android,Canvas,从Android、canvas和作品开始。我有可以在图形对象上绘制形状的现有Java代码。我正试图在一个带有Canvas的Android应用程序中使用该代码。基本上,我试图避免重构所有Java代码以显式使用Canvas。所以我正在制作我自己的“图形”对象。它所要做的就是调用适当的Canvas方法来绘制指定的形状 我在这里读过多篇关于不能在onDraw()方法之外使用canvas对象的文章。据我所知,您不能将canvas对象传递给其他类并期望它正常工作。但我也不完全了解这一切是如何运作的 应用程序
onDraw()
方法之外使用canvas对象的文章。据我所知,您不能将canvas对象传递给其他类并期望它正常工作。但我也不完全了解这一切是如何运作的
应用程序在drawOval方法的Graphics类中崩溃。我已经读了一本关于所有这些的日志,但是我还没有找到一个好的答案来解释为什么这不起作用。
我还没有找到一种方法以java友好的方式获取崩溃日志(也称为stacktrace)。它只是在tid 1520中抛出致命信号11(SIGSEGV)、代码1、故障地址0x130
谢谢!如果需要更多细节,请告诉我。这是我的密码:
main活动
public class MainActivity extends AppCompatActivity {
MyCanvas canvas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
canvas = new MyCanvas(this);
setContentView(canvas);
}
}
MyCanvas视图
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);
}
}
您对能够将
画布
传递给不同的类有一点误解。这绝对没有错,;将画布传递给类方法实际上与将其传递给常规函数相同。即使将Canvas
引用存储在成员变量中也不会有任何影响
但是,只有在理解到Canvas
不能在draw()
/onDraw()
方法的范围之外使用时,上述内容才是正确的。也就是说,任何使用Canvas
的方法都必须从onDraw()
中调用,或者从onDraw()调用的函数中调用
这是因为Canvas
是在onDraw()
之前初始化的(由框架),以便为当前绘图操作做好准备。您可能希望将其视为使用位图
初始化画布
,该位图将用作此特定屏幕框的绘图输出面(这与事实并不遥远)。返回onDraw()
后,框架将假定您的代码不再使用它,并且它可以将输出表面/位图
/等提交给屏幕合成器进行渲染,而无需担心进一步的修改
而且,您的方法是一种很好的方法,它是一种调整现有代码以使用新图形对象的技术
因此,为了解决这个问题:在正常的Android开发中,当您不(直接)处理本机/JNI例程时,SIGSEGVs不应该发生。但是,我突然想到,如果Canvas
对象发生更改,您不会更新它。这可能会导致崩溃(在本机代码中,这就是为什么您没有获得Java堆栈跟踪)。在给您一张较新的画布之后,您使用了一张旧的画布。如果(this.canvas==null)删除条件,您应该会没事。好的,是的,您肯定确认了我对它的一些想法。我认为使用其他地方的Canvas
会引起问题。基本上,流程从我的onDraw
方法,到我自己的JavaShape
代码,其中有一个渲染方法,它接受一个Graphics
对象。然后通过调用graphics.drawOval()
使用该图形对象,就像使用JavaAWT一样。因为我不能使用它,所以我正在创建自己的图形类,它只接收调用canvas.drawCircle()
所需的参数。所以除此之外,我没有使用任何其他第三方库。@pianoman102抱歉,刚刚更新了我的答案。请重新阅读最后一段:)经过一些调试,我确信在我的图形类中执行canvas.drawCircle()
后它会崩溃。哦,我现在明白了。所以每次调用onDraw()
时它都是一个新的画布对象?这是为什么,又是如何起作用的?对我来说,这似乎是一个很大的重复。@pianoman102我不确定框架每次提供不同画布对象的确切原因。但是,它相当轻;只是位图
和视图
(或视图树)之间的绑定。只是b/c你得到了一个新的画布
,并不意味着有很多重新渲染,但是你可能会惊讶地知道,事实上,Android每次都会重新渲染整个视图,即使是最小的更改(通常)。没有太多的阐述,这是因为它简化了onDraw()
实现、合成、alpha混合以及基于硬件的表面使用的细节。
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
}
}