有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Android:应用程序在反压SurfaceView上崩溃

我正在开发一款安卓应用程序,刚刚创建了背景画布。应用程序加载正常,但当我按下后退按钮(即关闭应用程序)时,应用程序崩溃。查看logcat(见下文),我得到一个NullPointerException。有人知道我能解决这个问题吗

以下是我的课程:

package pmm.antiaircraft1;

import 安卓.app.Activity;
import 安卓.view.Window;
import 安卓.view.WindowManager;

public class GameActivity extends Activity {

  private GameThread mGameThread;

  public void onStart() {
    super.onStart();
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.main);
    mGameThread = ((GameView) findViewById(R.id.game)).getThread();
    mGameThread.createGraphics();
  }
}
package pmm.antiaircraft1;

import 安卓.content.Context;
import 安卓.content.res.Resources;
import 安卓.graphics.Bitmap;
import 安卓.graphics.BitmapFactory;
import 安卓.graphics.Canvas;
import 安卓.os.Handler;
import 安卓.util.DisplayMetrics;
import 安卓.view.SurfaceHolder;

public class GameThread extends Thread {
  private SurfaceHolder mSurfaceHolder;
  public DisplayMetrics metrics = new DisplayMetrics();
  private static Bitmap mBackgroundImage;
  public static Bitmap tankImg;
  public static Bitmap cannonImg;
  public static boolean mRun = false;
  private Tank tank;
  public static Resources res;

  public GameThread(SurfaceHolder surfaceHolder, Context context, Handler handler) {
    mSurfaceHolder = surfaceHolder;
    Resources res = context.getResources();
    mBackgroundImage = BitmapFactory.decodeResource(res, R.drawable.background);
    tankImg = BitmapFactory.decodeResource(res, R.drawable.tank);
    cannonImg = BitmapFactory.decodeResource(res, R.drawable.cannon);
  }

  @
  Override
  public void run() {
    while (mRun) {
      Canvas c = null;
      try {
        c = mSurfaceHolder.lockCanvas(null);
        synchronized(mSurfaceHolder) {
          draw(c);
        }
      } finally {
        if (c != null) {
          mSurfaceHolder.unlockCanvasAndPost(c);
        }
      }
    }
  }

  public void setRunning(boolean b) {
    mRun = b;
  }

  private void draw(Canvas canvas) {
    canvas.drawBitmap(mBackgroundImage, 0, 0, null);
    tank.draw(canvas);
  }

  public void createGraphics() {
    mBackgroundImage = Bitmap.createBitmap(mBackgroundImage);
    tank = new Tank();
  }
}
package pmm.antiaircraft5;

import 安卓.content.Context;
import 安卓.util.AttributeSet;
import 安卓.view.SurfaceHolder;
import 安卓.view.SurfaceView;

public class GameView extends SurfaceView implements SurfaceHolder.Callback {
  private GameThread thread;

  public GameView(Context context, AttributeSet attrs) {
    super(context, attrs);
    SurfaceHolder holder = getHolder();
    holder.addCallback(this);
    thread = new GameThread(holder, context, null);
  }

  public GameThread getThread() {
    return thread;
  }

  public void surfaceCreated(SurfaceHolder holder) {

    thread.setRunning(true);
    thread.start();

  }


  @
  Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width,
    int height) {}

  @
  Override
  public void surfaceDestroyed(SurfaceHolder holder) {
    this.setWillNotDraw(false);

  }
}
package pmm.antiaircraft1;

import 安卓.graphics.Bitmap;
import 安卓.graphics.Canvas;
import 安卓.graphics.Matrix;

public class Tank {
    private static final int TANK_HEIGHT = 50;
    private static final int TANK_WIDTH = 50;
    private static final int TANK_TOP = 480 - TANK_HEIGHT;
    private static final int CANNON_WIDTH = 10;

    public Tank(){
        GameThread.tankImg=Bitmap.createBitmap(GameThread.tankImg);
        GameThread.cannonImg=Bitmap.createBitmap(GameThread.cannonImg);
    }

    public void draw(Canvas c) {
        c.drawBitmap(GameThread.tankImg, (320-TANK_WIDTH)/2, TANK_TOP, null);   
        Matrix m = new Matrix();
        m.postTranslate((320-CANNON_WIDTH)/2, TANK_TOP - 30);
        c.drawBitmap(GameThread.cannonImg, m, null);    
    }
}

日志输出:

W/SurfaceView(400): CHECK surface infomation creating=false formatChanged=false sizeChanged=false visible=false visibleChanged=true surfaceChanged=true realSizeChanged=false redrawNeeded=false left=false top=false
**E/AndroidRuntime(400): FATAL EXCEPTION: Thread-88523
E/AndroidRuntime(400): java.lang.NullPointerException
E/AndroidRuntime(400): at pmm.antiaircraft1.GameThread.draw(GameThread.java:52)
E/AndroidRuntime(400): at pmm.antiaircraft1.GameThread.run(GameThread.java:37)**
W/SurfaceView(400): CHECK surface infomation creating=false formatChanged=false sizeChanged=false visible=false visibleChanged=false surfaceChanged=false realSizeChanged=false redrawNeeded=false left=false top=false
03-29 01:56:46.565: W/SurfaceView(400): CHECK surface infomation creating=false formatChanged=false sizeChanged=false visible=false visibleChanged=false surfaceChanged=false realSizeChanged=false redrawNeeded=false left=false top=false

共 (1) 个答案

  1. # 1 楼答案

    SurfaceView生命周期与活动生命周期并不完全相同。如果在run()中检查lockCanvas()的结果,并且当它为空时不尝试绘制,那么应该能够避免崩溃,而不会出现任何可见的小故障

    为了更仔细地执行此操作,并避免其他潜在问题,需要使用表面回调来跟踪当前状态。可以在图形体系结构文档in an appendix中找到解释,在Grafika中可以找到示例(例如“multi-surface test”活动)