title: SurfaceView onDraw, at times doesn't refresh itself before draw... why?
body: <p>I have a simple onDraw method as below (in 'SurfaceView'), where the 'startCount' will go from 1 to 360,  the filled circle get drawn.</p>
  
  <pre><code>@Override
  protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      //canvas.drawColor(0xFFEEEEEE);
      if (startCount == 360) startCount= 0;
      canvas.drawArc(mShadowBounds,
              0, startCount, true, mPiePaint);
  }
  </code></pre>
  
  <p>And after complete a cycle. It will continue refresh and redrawn itself again from the beginning like radar detector moving.</p>
  
  <p>The odd things is, at times, after a complete cycle, it doesn't refresh, so the big black circle is shown instead. </p>
  
  <p>Illustration in <a href="https://youtu.be/sc56FYUqV7M" rel="nofollow">https://youtu.be/sc56FYUqV7M</a>, the first 2 cycles is what I expect. However when it completes the second cycle, it remains all black moving forward, which is strange it didn't remove previous drawing. I'm expecting it to repeat itself like how it did on the second cycle.</p>
  
  <p>This doesn't always happens after the second cycle. At times one should wait a while after many cycles before it happen, without any interference (i.e. not touching the device). Hard to predict when it will happen. </p>
  
  <p>What's the cause of it? How to even debug on this issue?</p>
  
  <p>(FYI. I could use the same algorithm on the 'onDraw' in 'View' class. This issue doesn't happen at all.)</p>
  
  <p>Attached below the complete code for Custom Surface View and it's Thread code.</p>
  
  <pre><code>public class TimerSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
  
      private Paint mPiePaint;
      private RectF mShadowBounds;
      private float diameter;
  
      int startCount = 0;
      private PanelThread thread;
  
      public TimerSurfaceView(Context context) {
          super(context);
          init();
      }
  
      public TimerSurfaceView(Context context, AttributeSet attrs) {
          super(context, attrs);
          init();
      }
  
      public TimerSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
          super(context, attrs, defStyleAttr);
          init();
      }
  
      @TargetApi(VERSION_CODES.LOLLIPOP)
      public TimerSurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
          super(context, attrs, defStyleAttr, defStyleRes);
          init();
      }
  
      private void init() {
          getHolder().addCallback(this);
          mPiePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
          mPiePaint.setStyle(Paint.Style.FILL);
          mPiePaint.setColor(0xff000000);
  
          setZOrderOnTop(true);
          getHolder().setFormat(PixelFormat.TRANSLUCENT);
  
      }
  
      @Override
      protected void onSizeChanged(int w, int h, int oldw, int oldh) {
          super.onSizeChanged(w, h, oldw, oldh);
  
          // Account for padding
          float xpad = (float)(getPaddingLeft() + getPaddingRight());
          float ypad = (float)(getPaddingTop() + getPaddingBottom());
  
          float ww = (float)w - xpad;
          float hh = (float)h - ypad;
  
          // Figure out how big we can make the pie.
          diameter = Math.min(ww, hh);
          mShadowBounds = new RectF(0, 0, diameter, diameter);
  
      }
  
      @Override
      protected void onDraw(Canvas canvas) {
          super.onDraw(canvas);
          //canvas.drawColor(0xFFEEEEEE);
          if (startCount == 360) startCount= 0;
          canvas.drawArc(mShadowBounds,
                  0, startCount, true, mPiePaint);
      }
  
      public void incrementCount() {
          startCount++;
      }
  
      @Override
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
          int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();
          int w = resolveSizeAndState(minw, widthMeasureSpec, 1);
          int h = resolveSizeAndState(MeasureSpec.getSize(w), heightMeasureSpec, 0);
          setMeasuredDimension(w, h);
      }
  
      @Override
      public void surfaceCreated(SurfaceHolder holder) {
          setWillNotDraw(false); //Allows us to use invalidate() to call onDraw()
          thread = new PanelThread(getHolder(), this); //Start the thread that
          thread.setRunning(true);                     //will make calls to
          thread.start();                              //onDraw()
      }
  
      @Override
      public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  
      }
  
      @Override
      public void surfaceDestroyed(SurfaceHolder holder) {
          // tell the thread to shut down and wait for it to finish
          // this is a clean shutdown
          if (thread != null) {
              boolean retry = true;
              while (retry) {
                  try {
                      thread.setRunning(false);                //Tells thread to stop
                      thread.join();                           //Removes thread from mem.
                      retry = false;
                  } catch (InterruptedException e) {
                      // try again shutting down the thread
                  }
              }
              thread = null;
          }
      }
  }
  </code></pre>
  
  <p>And the Thread class</p>
  
  <pre><code>class PanelThread extends Thread {
      private SurfaceHolder surfaceHolder;
      private TimerSurfaceView panel;
      private boolean startRunning = false;
  
  
      public PanelThread(SurfaceHolder surfaceHolder, TimerSurfaceView panel) {
          this.surfaceHolder = surfaceHolder;
          this.panel = panel;
      }
  
  
      public void setRunning(boolean run) { //Allow us to stop the thread
          startRunning = run;
      }
  
  
      @Override
      public void run() {
          Canvas c;
          while (startRunning) {     //When setRunning(false) occurs, startRunning is
              c = null;      //set to false and loop ends, stopping thread
              try {
                  c = surfaceHolder.lockCanvas(null);
                  synchronized (surfaceHolder) {
                      //Insert methods to modify positions of items in onDraw()
                      panel.incrementCount();
                      panel.postInvalidate();
                  }
              } finally {
                  if (c != null) {
                      surfaceHolder.unlockCanvasAndPost(c);
                  }
              }
  
          }
      }
  }
  </code></pre>