在Android中绘制到画布会抛出空指针异常

时间:2014-02-24 23:32:57

标签: android android-canvas

我正在尝试创建一个背景的简单渲染,顶部有一个图像,大约每30秒更新一次。我正在使用画布来完成这项工作但是当我尝试打印到画布时它会抛出一个NPE。据我所知,画布已初始化。活动启动视图,该视图启动/停止运行draw方法的线程。在绘制方法中,NPE被抛出。这是开始这一切的活动:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    view = new GameView(this);
    setContentView(view);
    view.onCreate();
}

public void onPause() {
    super.onPause();
    view.onPause();
}

public void onResume() {
    super.onResume();
    view.onResume();
}

这些是我的Surface View的主要功能:

public GameView(Context context) {
    super(context);
    getHolder().addCallback(this);
    setFocusable(true);
}

public void onCreate() {
    _drawThread = new DrawThread(getHolder(), this);
}

synchronized public void draw(Canvas canvas) {
    canvas.getHeight(); //returns NPE
}

public void onResume() {
    if (!_drawThread.isAlive()) {
        _drawThread.setRunning(true);
        _drawThread.start();
    } else {
        _drawThread.setRunning(true);
    }
}

public void onPause() {
    boolean retry = true;
    _drawThread.setRunning(false);
    while (retry) {
        try {
            _drawThread.join();
            retry = false;
        } catch (InterruptedException e) {

        }
    }
}

我的绘制线程看起来像:

public void run() {
    Canvas c;
    while (_running) {
        c = null;
        try {
            c = _surfaceHolder.lockCanvas();
            synchronized (_surfaceHolder) {
                _game.draw(c);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        } finally {
            if (c != null) {
            _surfaceHolder.unlockCanvasAndPost(c);
            }
        }
    }
}

从我可以告诉画布以某种方式不会在创建绘制线程之前初始化导致NPE,但我看不出代码有什么问题。一点帮助或建议会很棒。

1 个答案:

答案 0 :(得分:0)

您需要使用SurfaceHolder.Callback注册自己的SurfaceHolder.Callback2SurfaceHolder,并确保在尝试绘制表面之前已创建表面。如果您在创建曲面之前尝试锁定画布,则它将无法为您提供Canvas对象。您通常不需要覆盖SurfaceView,而只需将其用作访问您希望绘制的背景表面的机制。