【问题标题】:Thread existing with uncaught exception存在未捕获异常的线程
【发布时间】:2013-10-07 18:32:26
【问题描述】:

首先我知道在stackoverflow上已经发布了类似的问题,但在这种情况下我似乎无法找到确切的问题。

我在 logcat 中收到一些错误消息,总体而言我的程序非常不稳定并且经常意外关闭。

10-07 180852.056 EAndroidRuntime(1043) FATAL EXCEPTION Thread-85

10-07 180852.056 EAndroidRuntime(1043) java.lang.NullPointerException

10-07 180852.056 EAndroidRuntime(1043)  at com.ophion.td2.GameEngine.Draw(GameEngine.java61)

10-07 180852.056 EAndroidRuntime(1043)  at com.ophion.td2.GameThread.run(GameThread.java46)

10-07 180854.046 IChoreographer(1043) Skipped 49 frames!  The application may be doing too much work on its main thread. The application may be doing too much work on its main thread.

10-07 180855.026 IProcess(1043) Sending signal. PID 1043 SIG 9'

那是 logcat,这里是我认为是问题所在的代码文件(我可能错了!)。游戏引擎:

public class GameEngine implements Runnable{

public int screenWidth;
public int screenHeight;
private Paint whitePaint;
private Paint textPaint;
/* private String currentTimeString */

Blop blop;
private Context context;

public void Init(Context context) {
    this.context = context;
    Resources resources = context.getResources();

    whitePaint = new Paint();
    whitePaint.setColor(Color.WHITE);
    whitePaint.setStyle(Style.FILL);

    textPaint = new Paint();
    textPaint.setColor(Color.LTGRAY);
    textPaint.setTextSize(40);

    blop = new Blop(resources, 20, 20);
    blop.setDirection(300);

    setSurfaceDimensions(240, 160);


}

public void onDestroy() {
    try {
    }   catch (Exception e) {

    }
}

public void setSurfaceDimensions(int width, int height) {
    screenWidth = width;
    screenHeight = height;
}

public void Update() {
    /*currentTimeString = new SimpleDateFormat("HH:mm:ss").format(new Date()); */
    blop.move(screenWidth, screenHeight);
}

public void Draw(Canvas canvas) {
    canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), whitePaint);
    /* canvas.drawText(currentTimeString, 30, 100, textPaint); */
    blop.draw(canvas, blop.x, blop.y, textPaint);
}

@Override
public void run() {
    // TODO Auto-generated method stub

}

}    

还有游戏线程

public class GameThread extends Thread {
private SurfaceHolder surfaceHolder;
private Canvas canvas;
private long delay = 1000000000L / 25;
private long beforeTime = 0;
private long afterTime = 0;
private long timeDiff = 0;
private long sleepTime;
private long overSleepTime = 0;
private long excess = 0;

public final static int RUNNING = 1;
public final static int PAUSED = 2;
public static final int MAX_FRAME_SKIPS = 5;
int state = RUNNING;

GameEngine gameEngine;

public GameThread(SurfaceHolder surfaceHolder, Context context,
    Handler handler, GameEngine gameEngine) {
    this.surfaceHolder = surfaceHolder;
    this.gameEngine = gameEngine;
}

@Override
public void run() {

    while (state == RUNNING) {
        beforeTime = System.nanoTime();

        gameEngine.Update();

        canvas = null;
        try {
            canvas = surfaceHolder.lockCanvas(null);
            synchronized (surfaceHolder) {
                gameEngine.Draw(canvas);
            }
        } finally {
            if (canvas != null) {
                surfaceHolder.unlockCanvasAndPost(canvas);
            }
        }

        afterTime = System.nanoTime();
        timeDiff = afterTime - beforeTime;
        sleepTime = ((delay) - timeDiff) - overSleepTime;

        if (sleepTime > 0) {
            try {
                sleep(sleepTime / 1000000L);
            } catch (InterruptedException ex) {
            }
            overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
        } else {
            excess -= sleepTime;
            overSleepTime = 0L;
        }

        int skips = 0;
        while ((excess > delay) && (skips < MAX_FRAME_SKIPS)) {
            excess -= delay;
            gameEngine.Update();
            skips++;
        }
    }
}
}

希望你能帮帮我!

【问题讨论】:

  • GameEngine 类中的#61 是哪一行?和线#46?
  • 什么时候给GameEngine.Init()打电话?
  • 当 run() 方法仍然是未使用的空方法存根时,从 Runnable() 派生的意义何在?也就是说,AFAICT 你在lockCanvas()synchronized(surfaceHolder) 之间有一个竞争条件。您必须在操作需要原子性的整个时间内同步共享对象。谈到共享对象,您甚至没有在同步部分中使用表面支架这一事实也是账单上的一个大问号......

标签: java android multithreading exception


【解决方案1】:

当您运行 Thread 时,gameEngine 似乎为空

【讨论】:

    【解决方案2】:

    我不想计算你的行号,但是你在 GameEngine 的 Draw() 方法中得到了 NullPointerException。这几乎肯定意味着当线程调用该方法时,您的 Canvas 为空,或者您的 blop 为空。第 61 行中的任何一个都是罪魁祸首。

    【讨论】:

      猜你喜欢
      • 2011-05-20
      • 2016-02-09
      • 2013-04-11
      • 2013-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-01
      • 2013-03-09
      相关资源
      最近更新 更多