我正在尝试实现一个,基于本教程从a SurfaceView调用它的onDraw()方法.在我开始运行以下代码后,我的应用程序正在提供ANR.Thread
我尝试过实现Runnable,而不是扩展Thread但它仍然给出了ANR.
据我所知,当ANR发生时,应用程序上没有其他任何东西在运行.(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 ");
}
}
Run Code Online (Sandbox Code Playgroud)
导致ANR的原因是什么?我应该以一种截然不同的方式实现Runnable或扩展Thread吗?
gamePanel从您的输入扩展SurfaceView并接收您的输入(通过onTouchEvent())。换句话说,它是您的 UI 线程。当您调用时,gamePanel.onDraw(canvas)它处于阻塞状态(等待硬件绘制canvas),因此您会收到 ANR。
似乎MainThread是渲染线程(看看它如何拥有 )canvas,并且它应该是唯一的渲染线程。您的游戏逻辑应该MainGamePanel完全放在一个单独的线程中。
所以理想情况下我会有三个线程:
| 归档时间: |
|
| 查看次数: |
1653 次 |
| 最近记录: |