Why does my runnable give ANR?

I am trying to implement SurfaceViewby calling its method onDraw()from Thread, based on this tutorial , My application provides ANR after running the code below.

I tried to implement Runnable instead of extension Thread, but it still gives ANR.

As far as I know, nothing works in the application when ANR takes place. (ANRs just started to appear when I added this 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 (<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 > 0) {
                        // if sleepTime > 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 < 0 && framesSkipped < 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 ");
    }
}

What causes ANR? Should I implement Runnableor expand in a Threadsignificantly different way?

+5
source share
2 answers

gamePanel SurfaceView ( onTouchEvent()). , . gamePanel.onDraw(canvas) ( canvas), ANR.

, MainThread (, canvas), . MainGamePanel .

:

  • ( , )
  • ( , )
  • ( )
+1

Thread.sleep(...) . , , . . .

, , , , .

+1

All Articles