我正在做一个操纵杆应用程序,其中按钮单击应该显示列表视图。但是,当我打开列表视图时,应用程序关闭时会显示一条关于具有空指针异常的画布的错误消息,因此无法获得画布的宽度/高度。 错误:
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);
}
}
你们有没有想过如何初始化画布以使其工作?
感谢我能得到的所有帮助!
答案 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);
}
通过遵循注释,我实现了一种方法,让线程在创建表面时执行,并且一旦它被销毁(在这种情况下,当新框架打开时)线程被取消。
干杯!