Android:canvas给出空指针异常 - 如何修复它?

时间:2016-03-15 19:54:48

标签: android pointers canvas android-asynctask null

我正在做一个操纵杆应用程序,其中按钮单击应该显示列表视图。但是,当我打开列表视图时,应用程序关闭时会显示一条关于具有空指针异常的画布的错误消息,因此无法获得画布的宽度/高度。 错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Canvas.getWidth()' on a null object reference

代码:

public class MySurfaceThread extends AsyncTask<Void, Void, Void>{

    SurfaceHolder mSurfaceHolder;
    CustomSurfaceView cSurfaceView;


    public MySurfaceThread(SurfaceHolder sh, CustomSurfaceView csv){
        mSurfaceHolder = sh;
        cSurfaceView = csv;
        x = y = 0;

        cSurfaceView.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                x = event.getX();
                y = event.getY();
                System.out.println(x + " " + y);

                calculateValues(x,y);

                switch (event.getAction() & MotionEvent.ACTION_MASK){
                    case MotionEvent.ACTION_DOWN:
                        break;
                    case MotionEvent.ACTION_UP:
                        x = y = 0;
                        dx = dy = 0;
                        break;
                    case MotionEvent.ACTION_CANCEL:
                        break;
                }
                return true;
            }

            private void calculateValues(float xx, float yy){
                dx = xx-zeroX;
                dy = yy-zeroY;
                angle = (float)Math.atan(Math.abs(dy / dx));
                c = (float)Math.sqrt(dx * dx + dy * dy);

                if(c > radius){
                    if (dx > 0 && dy > 0) { //lower right corner
                        xx = (float) (zeroX + radius * Math.cos(angle));
                        yy = (float) (zeroY + radius * Math.sin(angle));
                    }
                    else if(dx > 0 && dy < 0){ //top right corner
                        xx = (float) (zeroX + radius * Math.cos(angle));
                        yy = (float) (zeroY - radius * Math.sin(angle));
                    }
                    else if(dx < 0 && dy < 0){ //top left corner
                        xx = (float) (zeroX - radius * Math.cos(angle));
                        yy = (float) (zeroY - radius * Math.sin(angle));
                    }
                    else if(dx < 0 && dy > 0){ //lower left corner
                        xx = (float) (zeroX - radius * Math.cos(angle));
                        yy = (float) (zeroY + radius * Math.sin(angle));
                    }
                }
                else {
                    xx = zeroX + dx;
                    yy = zeroY + dy;
                }
                System.out.println("dx: " + dx);
                System.out.println("dy: " + dy);
                x = xx;
                y = yy;
            }
        });


    }


    //@Override
    protected Void doInBackground(Void... params) {


        while(run) {



            Canvas canvas = new Canvas();
            canvas.drawBitmap(background,0,0,null);
            cSurfaceView.surfaceCreated(mSurfaceHolder);



            try {

                canvas = mSurfaceHolder.lockCanvas(null);

                synchronized (mSurfaceHolder) {

                    zeroX = (1704-1704/8);
                    zeroY = (915-915/4);
                    cSurfaceView.onDraw(canvas, x, y, zeroX, zeroY);

                }
                Thread.sleep(10);
            } catch (InterruptedException e) {

            } finally {
                if (canvas != null) {
                    mSurfaceHolder.unlockCanvasAndPost(canvas);
                }

            }
        }
        return null;
    }
}

此外,如果需要 - 继承onDraw方法:

 protected void onDraw(Canvas canvas, float x, float y, float zx, float zy){

    dx = x-zx;
    dy = y-zy;

    super.onDraw(canvas);

    canvas.drawRGB(255, 255, 255);
    canvas.drawBitmap(background, (canvas.getWidth() - canvas.getWidth() / 7) - background.getWidth() / 2, (canvas.getHeight() - canvas.getHeight() / 4) - background.getHeight() / 2, null);
    canvas.drawText(Float.toString(x), 60, 60, paint1);
    canvas.drawText(Float.toString(y), 60, 120, paint1);

    if (x == 0 && y == 0) {
        canvas.drawBitmap(ball, (canvas.getWidth()-canvas.getWidth() / 7) - ball.getWidth() / 2, (canvas.getHeight()-canvas.getHeight() / 4) - ball.getHeight() / 2, null);

    }
    else {
        canvas.drawBitmap(ball, x - ball.getWidth() / 2, y - ball.getHeight() / 2, null);
    }
}

你们有没有想过如何初始化画布以使其工作?

感谢我能得到的所有帮助!

1 个答案:

答案 0 :(得分:0)

感谢Gabe的解释,我让它使用以下代码进行回调。

 public void surfaceCreated(SurfaceHolder arg0) {
    Surface surface = arg0.getSurface();


    if (surface != null){
        thread.execute((Void[])null);
    }


}

public void surfaceDestroyed(SurfaceHolder arg0) {

    thread.cancel(true);

}

通过遵循注释,我实现了一种方法,让线程在创建表面时执行,并且一旦它被销毁(在这种情况下,当新框架打开时)线程被取消。

干杯!