finally块完成后抛出NullPointerException

时间:2011-05-27 06:50:28

标签: java android nullpointerexception try-finally

我正在尝试制作Android游戏,我正在关注一些代码示例以使我的游戏循环正常工作。它涉及制作一个新线程。在run()方法中,我有一个try / finally块。在finally块执行后,抛出NullPointerException。我不知道为什么,似乎没有任何东西,即使它是,没有任何东西引用任何null。我想也许this是空的但似乎不是。这是我认为相关的代码:

public class MainThread extends Thread {
private boolean running;
private final SurfaceHolder holder;

private boolean GameIsRunning = false;

private int mMode;
public static final int STATE_LOSE = 1;
public static final int STATE_PAUSE = 2;
public static final int STATE_READY = 3;
public static final int STATE_RUNNING = 4;
public static final int STATE_WIN = 5;

private MainGame game;

public MainThread(SurfaceHolder holder, MainGamePanel panel) {
    super();
    this.holder = holder;
    game = new MainGame(panel.getContext());
    mMode = STATE_RUNNING;
}

@Override
public void run() {
    while (running) {
        Canvas c = null;
        try {
            c = holder.lockCanvas(null);
            synchronized (holder) {
                if (mMode == STATE_RUNNING) {
                    updateAll();
                }
                drawAll(c);
            }
        } finally {
            // do this in a finally so that if an exception is thrown
            // during the above, we don't leave the Surface in an
            // inconsistent state
            if (c != null) {
                holder.unlockCanvasAndPost(c);
            }
        } // <<<<<<<<<<<<< After this line executes a null pointer exception is thrown
    } 
}

创建线程:

public class MainGamePanel extends SurfaceView implements SurfaceHolder.Callback{

private MainThread thread;

public MainGamePanel(Context context) {
    super(context);
    getHolder().addCallback(this);

    // create the game loop thread
    thread = new MainThread(getHolder(), this);
    setFocusable(true);
}


@Override
public void surfaceCreated(SurfaceHolder holder) {
    thread.setRunning(true);
    thread.start();
}

谢谢!

2 个答案:

答案 0 :(得分:4)

NPE被抛入try块中,并在finally块执行后变为可见。

从查看代码时,很可能因为cnull传递给updateAll时发生null。你在finally块中有一个c == null检查 - 所以我猜你期望它可能是null。在try块中添加另一个检查并在那里处理SurfaceHolder#lockCanvas


来自android API({{1}}):

  

如果尚未创建表面或无法编辑表面,则返回 null

答案 1 :(得分:-1)

尝试将c = holder.lockCanvas(null);替换为c = holder.lockCanvas();

当然你应该发布你的堆栈跟踪。