私はthis tutorialに基づいてThread
からonDraw()
メソッドを呼び出すSurfaceView
を実装しようとしています。以下のコードを実行した後、私のアプリはANRを出しています。なぜ私の実行可能ファイルはANRを与えていますか?
Thread
の代わりにimplementing Runnableを試しましたが、それでもANRが得られました。
限り、ANRが発生したときに私はアプリでthere's nothing else runningを知っています。 (このコードを追加すると、ANRが発生し始めました:)
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 ");
}
}
ANRの原因は何ですか?大幅に異なる方法でRunnable
を実装するか、Thread
を拡張する必要がありますか?
を描画するための
Logcatを投稿できますか? –
@Balaji私はrunOnUiThreadを見たことがあるが、この場合は忘れてしまった。また、申し訳ありませんがLogCatの出力を投稿できませんでした。私は基本的に問題を再び引き起こす前にそれを解決しました。 :-) –