Using Android canvas in different class, debug crash errors









up vote
0
down vote

favorite












Just starting out with Android, canvas, the works. I have existing Java code that can draw shapes on a graphics object. I am trying to use that code in an Android app with Canvas. Basically, I'm trying to avoid refactoring all of my Java code to use Canvas explicitly. So I'm in the process of making my own "Graphics" object. All it should do is call the appropriate Canvas methods to draw the specified shape.



I've read multiple posts here about not being able to use the canvas object outside of the onDraw() method. From what I understand, you can't pass a canvas object to a different class and expect it to work correctly. But I also do not have a complete understanding of how all this works.



The app crashes in the Graphics class in the drawOval method. I've read up a log about all of this, but I haven't found a good answer as to why this specifically doesn't work.
I haven't been able to find a way to get crash logs in a java friendly way (aka a stacktrace). It just throws Fatal signal 11 (SIGSEGV), code 1, fault addr 0x130 in tid 1520.



Thanks! Let me know if more details are needed. Here's my code:



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











share|improve this question

























    up vote
    0
    down vote

    favorite












    Just starting out with Android, canvas, the works. I have existing Java code that can draw shapes on a graphics object. I am trying to use that code in an Android app with Canvas. Basically, I'm trying to avoid refactoring all of my Java code to use Canvas explicitly. So I'm in the process of making my own "Graphics" object. All it should do is call the appropriate Canvas methods to draw the specified shape.



    I've read multiple posts here about not being able to use the canvas object outside of the onDraw() method. From what I understand, you can't pass a canvas object to a different class and expect it to work correctly. But I also do not have a complete understanding of how all this works.



    The app crashes in the Graphics class in the drawOval method. I've read up a log about all of this, but I haven't found a good answer as to why this specifically doesn't work.
    I haven't been able to find a way to get crash logs in a java friendly way (aka a stacktrace). It just throws Fatal signal 11 (SIGSEGV), code 1, fault addr 0x130 in tid 1520.



    Thanks! Let me know if more details are needed. Here's my code:



    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











    share|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      Just starting out with Android, canvas, the works. I have existing Java code that can draw shapes on a graphics object. I am trying to use that code in an Android app with Canvas. Basically, I'm trying to avoid refactoring all of my Java code to use Canvas explicitly. So I'm in the process of making my own "Graphics" object. All it should do is call the appropriate Canvas methods to draw the specified shape.



      I've read multiple posts here about not being able to use the canvas object outside of the onDraw() method. From what I understand, you can't pass a canvas object to a different class and expect it to work correctly. But I also do not have a complete understanding of how all this works.



      The app crashes in the Graphics class in the drawOval method. I've read up a log about all of this, but I haven't found a good answer as to why this specifically doesn't work.
      I haven't been able to find a way to get crash logs in a java friendly way (aka a stacktrace). It just throws Fatal signal 11 (SIGSEGV), code 1, fault addr 0x130 in tid 1520.



      Thanks! Let me know if more details are needed. Here's my code:



      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











      share|improve this question













      Just starting out with Android, canvas, the works. I have existing Java code that can draw shapes on a graphics object. I am trying to use that code in an Android app with Canvas. Basically, I'm trying to avoid refactoring all of my Java code to use Canvas explicitly. So I'm in the process of making my own "Graphics" object. All it should do is call the appropriate Canvas methods to draw the specified shape.



      I've read multiple posts here about not being able to use the canvas object outside of the onDraw() method. From what I understand, you can't pass a canvas object to a different class and expect it to work correctly. But I also do not have a complete understanding of how all this works.



      The app crashes in the Graphics class in the drawOval method. I've read up a log about all of this, but I haven't found a good answer as to why this specifically doesn't work.
      I haven't been able to find a way to get crash logs in a java friendly way (aka a stacktrace). It just throws Fatal signal 11 (SIGSEGV), code 1, fault addr 0x130 in tid 1520.



      Thanks! Let me know if more details are needed. Here's my code:



      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








      java android canvas






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 9 at 21:05









      pianoman102

      409




      409






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote



          accepted










          You have a slight misunderstanding about being able to pass a Canvas to different classes. There is absolutely nothing wrong with that; passing a canvas to a class method is effectively the same as passing it to a regular function. Even storing the Canvas reference in a member variable isn't going to hurt anything.



          HOWEVER, the above is only true with the understanding that the Canvas cannot be used outside the bounds of the draw()/onDraw() method. That is, any method that uses the Canvas must be called from within onDraw(), or a function called by onDraw(), etc.



          This is because the Canvas is initialized (by the framework) immediately before onDraw(), in order to prepare for the current drawing operation. You might wish to think of it as initializing the Canvas with a Bitmap that will serve as the drawing output surface for this particular screen frame (which is not far from the truth). Once onDraw() has returned, the framework assumes your code will no longer be using it, and it can submit the output surface/Bitmap/etc. to the screen compositor for rendering, without fear of further alterations.



          And, your approach is a good one, as a technique for adapting existing code to use a novel graphics object.



          So, to address the crash: SIGSEGVs should never happen in normal Android development when you're not dealing (directly) with native/JNI routines. However, it occurs to me that you're not updating the Canvas object in the event it changes. This could be causing the crash (in native code, which is why you don't get a Java stack trace). You used an old Canvas after a newer one was given to you. Remove the condition if (this.canvas == null) and you should be fine.






          share|improve this answer






















          • Ok, yeah you definitely confirmed some of the thoughts I had about it. I figured using Canvas from somewhere else would cause issues. Basically, the flow goes from my onDraw method, to my own Java Shape code where there is a render method that takes a Graphics object. That graphics object is then used by calling graphics.drawOval() as you would with Java awt. Since I can't use that, I'm making my own Graphics class that simply receives the parameters necessary to call a canvas.drawCircle(). So other than that, I'm not using any other 3rd party libraries.
            – pianoman102
            Nov 9 at 23:39










          • @pianoman102 Sorry, just updated my answer. Please re-read the last paragraph :)
            – greeble31
            Nov 9 at 23:39











          • After some debugging, I know for sure that it's crashing after executing the canvas.drawCircle() in my Graphics class.
            – pianoman102
            Nov 9 at 23:40










          • oh I see now. So it's a new Canvas object every time onDraw() is called? Why and how does that work? That seems like a lot of rerendering to me.
            – pianoman102
            Nov 9 at 23:42







          • 1




            @pianoman102 I'm unsure of the precise reason the framework provides a different Canvas object each time. But, it's fairly lightweight; just a binding between a Bitmap and a View (or view tree). Just b/c you're getting a new Canvas does not imply there's a lot of re-rendering, but you may be surprised to know that Android does, in fact, re-render the whole view each time even the smallest change is made (generally). Without expounding on that too much, it's because that simplifies onDraw() implementations, compositing, alpha mixing, and the details of the hardware-based surface usage.
            – greeble31
            Nov 9 at 23:50











          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53233261%2fusing-android-canvas-in-different-class-debug-crash-errors%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          1
          down vote



          accepted










          You have a slight misunderstanding about being able to pass a Canvas to different classes. There is absolutely nothing wrong with that; passing a canvas to a class method is effectively the same as passing it to a regular function. Even storing the Canvas reference in a member variable isn't going to hurt anything.



          HOWEVER, the above is only true with the understanding that the Canvas cannot be used outside the bounds of the draw()/onDraw() method. That is, any method that uses the Canvas must be called from within onDraw(), or a function called by onDraw(), etc.



          This is because the Canvas is initialized (by the framework) immediately before onDraw(), in order to prepare for the current drawing operation. You might wish to think of it as initializing the Canvas with a Bitmap that will serve as the drawing output surface for this particular screen frame (which is not far from the truth). Once onDraw() has returned, the framework assumes your code will no longer be using it, and it can submit the output surface/Bitmap/etc. to the screen compositor for rendering, without fear of further alterations.



          And, your approach is a good one, as a technique for adapting existing code to use a novel graphics object.



          So, to address the crash: SIGSEGVs should never happen in normal Android development when you're not dealing (directly) with native/JNI routines. However, it occurs to me that you're not updating the Canvas object in the event it changes. This could be causing the crash (in native code, which is why you don't get a Java stack trace). You used an old Canvas after a newer one was given to you. Remove the condition if (this.canvas == null) and you should be fine.






          share|improve this answer






















          • Ok, yeah you definitely confirmed some of the thoughts I had about it. I figured using Canvas from somewhere else would cause issues. Basically, the flow goes from my onDraw method, to my own Java Shape code where there is a render method that takes a Graphics object. That graphics object is then used by calling graphics.drawOval() as you would with Java awt. Since I can't use that, I'm making my own Graphics class that simply receives the parameters necessary to call a canvas.drawCircle(). So other than that, I'm not using any other 3rd party libraries.
            – pianoman102
            Nov 9 at 23:39










          • @pianoman102 Sorry, just updated my answer. Please re-read the last paragraph :)
            – greeble31
            Nov 9 at 23:39











          • After some debugging, I know for sure that it's crashing after executing the canvas.drawCircle() in my Graphics class.
            – pianoman102
            Nov 9 at 23:40










          • oh I see now. So it's a new Canvas object every time onDraw() is called? Why and how does that work? That seems like a lot of rerendering to me.
            – pianoman102
            Nov 9 at 23:42







          • 1




            @pianoman102 I'm unsure of the precise reason the framework provides a different Canvas object each time. But, it's fairly lightweight; just a binding between a Bitmap and a View (or view tree). Just b/c you're getting a new Canvas does not imply there's a lot of re-rendering, but you may be surprised to know that Android does, in fact, re-render the whole view each time even the smallest change is made (generally). Without expounding on that too much, it's because that simplifies onDraw() implementations, compositing, alpha mixing, and the details of the hardware-based surface usage.
            – greeble31
            Nov 9 at 23:50















          up vote
          1
          down vote



          accepted










          You have a slight misunderstanding about being able to pass a Canvas to different classes. There is absolutely nothing wrong with that; passing a canvas to a class method is effectively the same as passing it to a regular function. Even storing the Canvas reference in a member variable isn't going to hurt anything.



          HOWEVER, the above is only true with the understanding that the Canvas cannot be used outside the bounds of the draw()/onDraw() method. That is, any method that uses the Canvas must be called from within onDraw(), or a function called by onDraw(), etc.



          This is because the Canvas is initialized (by the framework) immediately before onDraw(), in order to prepare for the current drawing operation. You might wish to think of it as initializing the Canvas with a Bitmap that will serve as the drawing output surface for this particular screen frame (which is not far from the truth). Once onDraw() has returned, the framework assumes your code will no longer be using it, and it can submit the output surface/Bitmap/etc. to the screen compositor for rendering, without fear of further alterations.



          And, your approach is a good one, as a technique for adapting existing code to use a novel graphics object.



          So, to address the crash: SIGSEGVs should never happen in normal Android development when you're not dealing (directly) with native/JNI routines. However, it occurs to me that you're not updating the Canvas object in the event it changes. This could be causing the crash (in native code, which is why you don't get a Java stack trace). You used an old Canvas after a newer one was given to you. Remove the condition if (this.canvas == null) and you should be fine.






          share|improve this answer






















          • Ok, yeah you definitely confirmed some of the thoughts I had about it. I figured using Canvas from somewhere else would cause issues. Basically, the flow goes from my onDraw method, to my own Java Shape code where there is a render method that takes a Graphics object. That graphics object is then used by calling graphics.drawOval() as you would with Java awt. Since I can't use that, I'm making my own Graphics class that simply receives the parameters necessary to call a canvas.drawCircle(). So other than that, I'm not using any other 3rd party libraries.
            – pianoman102
            Nov 9 at 23:39










          • @pianoman102 Sorry, just updated my answer. Please re-read the last paragraph :)
            – greeble31
            Nov 9 at 23:39











          • After some debugging, I know for sure that it's crashing after executing the canvas.drawCircle() in my Graphics class.
            – pianoman102
            Nov 9 at 23:40










          • oh I see now. So it's a new Canvas object every time onDraw() is called? Why and how does that work? That seems like a lot of rerendering to me.
            – pianoman102
            Nov 9 at 23:42







          • 1




            @pianoman102 I'm unsure of the precise reason the framework provides a different Canvas object each time. But, it's fairly lightweight; just a binding between a Bitmap and a View (or view tree). Just b/c you're getting a new Canvas does not imply there's a lot of re-rendering, but you may be surprised to know that Android does, in fact, re-render the whole view each time even the smallest change is made (generally). Without expounding on that too much, it's because that simplifies onDraw() implementations, compositing, alpha mixing, and the details of the hardware-based surface usage.
            – greeble31
            Nov 9 at 23:50













          up vote
          1
          down vote



          accepted







          up vote
          1
          down vote



          accepted






          You have a slight misunderstanding about being able to pass a Canvas to different classes. There is absolutely nothing wrong with that; passing a canvas to a class method is effectively the same as passing it to a regular function. Even storing the Canvas reference in a member variable isn't going to hurt anything.



          HOWEVER, the above is only true with the understanding that the Canvas cannot be used outside the bounds of the draw()/onDraw() method. That is, any method that uses the Canvas must be called from within onDraw(), or a function called by onDraw(), etc.



          This is because the Canvas is initialized (by the framework) immediately before onDraw(), in order to prepare for the current drawing operation. You might wish to think of it as initializing the Canvas with a Bitmap that will serve as the drawing output surface for this particular screen frame (which is not far from the truth). Once onDraw() has returned, the framework assumes your code will no longer be using it, and it can submit the output surface/Bitmap/etc. to the screen compositor for rendering, without fear of further alterations.



          And, your approach is a good one, as a technique for adapting existing code to use a novel graphics object.



          So, to address the crash: SIGSEGVs should never happen in normal Android development when you're not dealing (directly) with native/JNI routines. However, it occurs to me that you're not updating the Canvas object in the event it changes. This could be causing the crash (in native code, which is why you don't get a Java stack trace). You used an old Canvas after a newer one was given to you. Remove the condition if (this.canvas == null) and you should be fine.






          share|improve this answer














          You have a slight misunderstanding about being able to pass a Canvas to different classes. There is absolutely nothing wrong with that; passing a canvas to a class method is effectively the same as passing it to a regular function. Even storing the Canvas reference in a member variable isn't going to hurt anything.



          HOWEVER, the above is only true with the understanding that the Canvas cannot be used outside the bounds of the draw()/onDraw() method. That is, any method that uses the Canvas must be called from within onDraw(), or a function called by onDraw(), etc.



          This is because the Canvas is initialized (by the framework) immediately before onDraw(), in order to prepare for the current drawing operation. You might wish to think of it as initializing the Canvas with a Bitmap that will serve as the drawing output surface for this particular screen frame (which is not far from the truth). Once onDraw() has returned, the framework assumes your code will no longer be using it, and it can submit the output surface/Bitmap/etc. to the screen compositor for rendering, without fear of further alterations.



          And, your approach is a good one, as a technique for adapting existing code to use a novel graphics object.



          So, to address the crash: SIGSEGVs should never happen in normal Android development when you're not dealing (directly) with native/JNI routines. However, it occurs to me that you're not updating the Canvas object in the event it changes. This could be causing the crash (in native code, which is why you don't get a Java stack trace). You used an old Canvas after a newer one was given to you. Remove the condition if (this.canvas == null) and you should be fine.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 10 at 0:26

























          answered Nov 9 at 23:30









          greeble31

          1,0331412




          1,0331412











          • Ok, yeah you definitely confirmed some of the thoughts I had about it. I figured using Canvas from somewhere else would cause issues. Basically, the flow goes from my onDraw method, to my own Java Shape code where there is a render method that takes a Graphics object. That graphics object is then used by calling graphics.drawOval() as you would with Java awt. Since I can't use that, I'm making my own Graphics class that simply receives the parameters necessary to call a canvas.drawCircle(). So other than that, I'm not using any other 3rd party libraries.
            – pianoman102
            Nov 9 at 23:39










          • @pianoman102 Sorry, just updated my answer. Please re-read the last paragraph :)
            – greeble31
            Nov 9 at 23:39











          • After some debugging, I know for sure that it's crashing after executing the canvas.drawCircle() in my Graphics class.
            – pianoman102
            Nov 9 at 23:40










          • oh I see now. So it's a new Canvas object every time onDraw() is called? Why and how does that work? That seems like a lot of rerendering to me.
            – pianoman102
            Nov 9 at 23:42







          • 1




            @pianoman102 I'm unsure of the precise reason the framework provides a different Canvas object each time. But, it's fairly lightweight; just a binding between a Bitmap and a View (or view tree). Just b/c you're getting a new Canvas does not imply there's a lot of re-rendering, but you may be surprised to know that Android does, in fact, re-render the whole view each time even the smallest change is made (generally). Without expounding on that too much, it's because that simplifies onDraw() implementations, compositing, alpha mixing, and the details of the hardware-based surface usage.
            – greeble31
            Nov 9 at 23:50

















          • Ok, yeah you definitely confirmed some of the thoughts I had about it. I figured using Canvas from somewhere else would cause issues. Basically, the flow goes from my onDraw method, to my own Java Shape code where there is a render method that takes a Graphics object. That graphics object is then used by calling graphics.drawOval() as you would with Java awt. Since I can't use that, I'm making my own Graphics class that simply receives the parameters necessary to call a canvas.drawCircle(). So other than that, I'm not using any other 3rd party libraries.
            – pianoman102
            Nov 9 at 23:39










          • @pianoman102 Sorry, just updated my answer. Please re-read the last paragraph :)
            – greeble31
            Nov 9 at 23:39











          • After some debugging, I know for sure that it's crashing after executing the canvas.drawCircle() in my Graphics class.
            – pianoman102
            Nov 9 at 23:40










          • oh I see now. So it's a new Canvas object every time onDraw() is called? Why and how does that work? That seems like a lot of rerendering to me.
            – pianoman102
            Nov 9 at 23:42







          • 1




            @pianoman102 I'm unsure of the precise reason the framework provides a different Canvas object each time. But, it's fairly lightweight; just a binding between a Bitmap and a View (or view tree). Just b/c you're getting a new Canvas does not imply there's a lot of re-rendering, but you may be surprised to know that Android does, in fact, re-render the whole view each time even the smallest change is made (generally). Without expounding on that too much, it's because that simplifies onDraw() implementations, compositing, alpha mixing, and the details of the hardware-based surface usage.
            – greeble31
            Nov 9 at 23:50
















          Ok, yeah you definitely confirmed some of the thoughts I had about it. I figured using Canvas from somewhere else would cause issues. Basically, the flow goes from my onDraw method, to my own Java Shape code where there is a render method that takes a Graphics object. That graphics object is then used by calling graphics.drawOval() as you would with Java awt. Since I can't use that, I'm making my own Graphics class that simply receives the parameters necessary to call a canvas.drawCircle(). So other than that, I'm not using any other 3rd party libraries.
          – pianoman102
          Nov 9 at 23:39




          Ok, yeah you definitely confirmed some of the thoughts I had about it. I figured using Canvas from somewhere else would cause issues. Basically, the flow goes from my onDraw method, to my own Java Shape code where there is a render method that takes a Graphics object. That graphics object is then used by calling graphics.drawOval() as you would with Java awt. Since I can't use that, I'm making my own Graphics class that simply receives the parameters necessary to call a canvas.drawCircle(). So other than that, I'm not using any other 3rd party libraries.
          – pianoman102
          Nov 9 at 23:39












          @pianoman102 Sorry, just updated my answer. Please re-read the last paragraph :)
          – greeble31
          Nov 9 at 23:39





          @pianoman102 Sorry, just updated my answer. Please re-read the last paragraph :)
          – greeble31
          Nov 9 at 23:39













          After some debugging, I know for sure that it's crashing after executing the canvas.drawCircle() in my Graphics class.
          – pianoman102
          Nov 9 at 23:40




          After some debugging, I know for sure that it's crashing after executing the canvas.drawCircle() in my Graphics class.
          – pianoman102
          Nov 9 at 23:40












          oh I see now. So it's a new Canvas object every time onDraw() is called? Why and how does that work? That seems like a lot of rerendering to me.
          – pianoman102
          Nov 9 at 23:42





          oh I see now. So it's a new Canvas object every time onDraw() is called? Why and how does that work? That seems like a lot of rerendering to me.
          – pianoman102
          Nov 9 at 23:42





          1




          1




          @pianoman102 I'm unsure of the precise reason the framework provides a different Canvas object each time. But, it's fairly lightweight; just a binding between a Bitmap and a View (or view tree). Just b/c you're getting a new Canvas does not imply there's a lot of re-rendering, but you may be surprised to know that Android does, in fact, re-render the whole view each time even the smallest change is made (generally). Without expounding on that too much, it's because that simplifies onDraw() implementations, compositing, alpha mixing, and the details of the hardware-based surface usage.
          – greeble31
          Nov 9 at 23:50





          @pianoman102 I'm unsure of the precise reason the framework provides a different Canvas object each time. But, it's fairly lightweight; just a binding between a Bitmap and a View (or view tree). Just b/c you're getting a new Canvas does not imply there's a lot of re-rendering, but you may be surprised to know that Android does, in fact, re-render the whole view each time even the smallest change is made (generally). Without expounding on that too much, it's because that simplifies onDraw() implementations, compositing, alpha mixing, and the details of the hardware-based surface usage.
          – greeble31
          Nov 9 at 23:50


















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53233261%2fusing-android-canvas-in-different-class-debug-crash-errors%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Use pre created SQLite database for Android project in kotlin

          Darth Vader #20

          Ondo