0
我在做一個遊戲杆應用程序,點擊按鈕應該顯示一個列表視圖。但是,當我打開列表視圖時,應用程序會關閉關於具有空指針異常的畫布的錯誤消息,因此無法獲取畫布的寬度/高度。 錯誤:Android:canvas給出空指針異常 - 如何解決它?
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);
}
}
你們是否有任何想法如何,我可以初始化畫布爲了它的工作?
欣賞我所能得到的所有幫助!
根據文檔:如果曲面尚未創建或以其他方式無法編輯,則返回null。你通常需要實現Callback.surfaceCreated來找出Surface何時可用。要麼它在尚未創建時被破壞。在表面準備好之前,您不應該運行此線程,並且在表面被破壞時將其殺死。 –
感謝您的回覆@gabesechan, 我仍然不確定如何檢查表面是否已創建。 到目前爲止,我已經嘗試在Callback.surfaceCreated中執行以下操作: public void surfaceCreated(SurfaceHolder arg0){ Surface surface = arg0.getSurface(); if(arg0!= null)thread.execute(); } } –