why is my runnable giving ANR?
<p>I'm trying to implement a <code>SurfaceView</code>, calling its <code>onDraw()</code> method from a <code>Thread</code>, based on <a href="http://obviam.net/index.php/the-android-game-loop/" rel="nofollow">this tutorial</a>.  My app is giving ANR after I start the below code running.</p>

<p>I have tried <a href="http://stackoverflow.com/questions/541487/java-implements-runnable-vs-extends-thread/541506#541506">implementing Runnable</a>, instead of extending <code>Thread</code> but it still gives ANR.</p>

<p>As far as I know <a href="http://stackoverflow.com/questions/6212459/why-this-handler-runnable-is-slowing-down-my-app-if-it-is-launched-on-a-service/6212531#6212531">there's nothing else running</a> on the app when the ANR occurs.   (The ANRs only started occurring when I added this code:)</p>

<pre><code>package com.thunderrabbit.run;

import android.graphics.Canvas;
import android.view.SurfaceHolder;

public class MainThread extends Thread {
    private final String TAG = this.getClass().getSimpleName();

    // desired fps
    private final static int    MAX_FPS = 50;
    // maximum number of frames to be skipped
    private final static int    MAX_FRAME_SKIPS = 5;
    // the frame period
    private final static int    FRAME_PERIOD = 1000 / MAX_FPS;  

    private SurfaceHolder surfaceHolder;
    private PageGLSurfaceView gamePanel;
    private boolean running;    // flag to hold game state
    private Canvas canvas;

    long beginTime;     // the time when the cycle begun
    long timeDiff;      // the time it took for the cycle to execute
    int sleepTime;      // ms to sleep (&lt;0 if we're behind)
    int framesSkipped;  // number of frames being skipped 

    public MainThread(SurfaceHolder surfaceHolder, MySurfaceView gamePanel) {
        super();
        this.surfaceHolder = surfaceHolder;
        this.gamePanel = gamePanel;
    }

    public void setRunning(boolean running) {
        this.running = running;
    }

    @Override
    public void run() {
        sleepTime = 0;
        while(running)
        {
            canvas = null;
            try
            {
                synchronized (surfaceHolder)
                {
                    canvas = surfaceHolder.lockCanvas();
                    beginTime = System.currentTimeMillis();
                                    // resetting the frames skipped
                    framesSkipped = 0;
                    // update game state
                    this.gamePanel.update();
                    // render state to the screen
                    // draws the canvas on the panel
                    this.gamePanel.render(canvas);
                    // calculate how long did the cycle take
                    timeDiff = System.currentTimeMillis() - beginTime;
                    // calculate sleep time
                    sleepTime = (int)(FRAME_PERIOD - timeDiff);

                    if (sleepTime &gt; 0) {
                        // if sleepTime &gt; 0 we're OK
                        try {
                            // send the thread to sleep for a short period
                            // very useful for battery saving
                            Thread.sleep(sleepTime);
                        } catch (InterruptedException e) {}
                    }

                    while (sleepTime &lt; 0 &amp;&amp; framesSkipped &lt; MAX_FRAME_SKIPS) {
                        // we need to catch up
                        // update without rendering
                        this.gamePanel.update();
                        // add frame period to check if in next frame
                        sleepTime += FRAME_PERIOD;
                        framesSkipped++;
                    }
                    beginTime = System.currentTimeMillis();
                    gamePanel.onDraw(canvas);
                }
            }
            finally
            {
                if (canvas != null)
                {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
            // update game state
            // render state to the screen
        }
        DebugLog.d(TAG, "Game loop executed ");
    }
}
</code></pre>

<p>What's causing the ANR?  Should I implement <code>Runnable</code> or extend <code>Thread</code> in a significantly different way?</p>
