Android:SurfaceView在surfaceDestroyed()

时间:2015-07-15 15:44:07

标签: java android multithreading

我知道之前已经提出了类似的问题,但这些解决方案都不适用于我。

我正在尝试为Android创建一个小型2D游戏,我在使用SurfaceView时遇到了一些问题。

我的主要活动目前如下:

public class MainActivity extends Activity {

private static final String TAG = "MainActivity";
private DrawingSurface drawingsurface;
private Game game;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(TAG, "onCreate()");

    setFullscreen();
    game = new Game();
    drawingsurface = new DrawingSurface(this, game);
    setContentView(drawingsurface);
}

private void setFullscreen() {
    // ...
}

}

如您所见,我将活动设置为全屏,创建一个新的SurfaceView(称为drawingSurface)并创建一个新的游戏实例。

我的SurfaceView(名为DrawingSurface)如下所示:

public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback {

private GameThread thread;
private static final String TAG = "DrawingSurface";


public DrawingSurface(Context context, Game game) {
    super(context);
    getHolder().addCallback(this);
    setFocusable(true);
    // create a new game rendering thread and pass it game so it can call the update() and render() functions of game:
    thread = new GameThread(getHolder(), this, game); 
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    Log.v(TAG, "surfaceCreated()");
    // start the rendering thread:
    thread.setRunning(true);
    thread.start();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    Log.v(TAG, "surfaceChanged()");
    // do I need to do anything in here?
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // stop the rendering thread:
    Log.v(TAG, "surfaceDestroyed()");
    thread.setRunning(false);
    boolean retry = true;
    while (retry) {
        try {
            thread.join();
        } catch (InterruptedException e) {
            // try again shutting down the thread
        }
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    // pass the touch event to the Game instance (to keep everything in on place)
    thread.game.onTouchEvent(event);
    return super.onTouchEvent(event);
}

@Override
protected void onDraw(Canvas canvas) {
    // I don't use onDraw(), instead I have my own update() and render() functions in my game thread
    super.onDraw(canvas);
}

}

这是我的游戏主题:

public class GameThread extends Thread {

private boolean running;
private SurfaceHolder surfaceHolder;
private DrawingSurface drawingSurface;
private static final String TAG = GameThread.class.getSimpleName();
protected Game game;

public GameThread(SurfaceHolder surfaceHolder, DrawingSurface drawingSurface, Game game) {
    super();
    this.surfaceHolder = surfaceHolder;
    this.drawingSurface = drawingSurface;
    this.game = game;
}

public void setRunning(boolean running) {
    this.running = running;
}

@SuppressLint("WrongCall")
@Override
public void run() {
    Log.d(TAG, "Starting game loop");

    long now;
    long dt;
    long last = System.currentTimeMillis();
    Canvas canvas;


    while (running) {
        Log.v(TAG, "GameThread running");
        canvas = null;

        /* try locking the canvas for exclusive
           pixel editing in the surface */

        try {
            canvas = this.surfaceHolder.lockCanvas();
            synchronized (this.surfaceHolder) {
                now = System.currentTimeMillis();
                dt = (now - last);

                this.game.update(dt);
                if(canvas != null)
                    this.game.render(canvas, dt);

                last = now;
            }
        } finally {
            /*in case of an exception the surface
              is not left in an inconsistent state */
            if (canvas != null) {
                this.surfaceHolder.unlockCanvasAndPost(canvas);
            }
        }

        if (dt < 16) {
            try {
                Thread.sleep(16 - dt);
            } catch (InterruptedException e) {

            }

        }
    }
}

}

这是游戏类:

公共课游戏{

private static final String TAG = "Game";
private static int playerRefPosX = 40;

private int playerY = 0;
private int playerVelY = 1;

public Game() {
    Log.v(TAG, "Game instance created");
}

public void update(long dt) {
    playerY += playerVelY * dt;
    if (playerY > 1800) {
        playerVelY = -playerVelY;
    }
    if (playerY < 0) {
        playerVelY = -playerVelY;
    }

}
public void render(Canvas canvas, long dt) {
    canvas.drawColor(Color.BLACK);
    // draw Player
    Paint paint = new Paint();
    paint.setTextSize(100);
    paint.setColor(new Color().rgb(255, 0, 0));
    canvas.drawRect(playerRefPosX, playerY + 100, playerRefPosX + 200, playerY - 100, paint);
    canvas.drawText(String.valueOf(1000/dt), canvas.getWidth()/2, canvas.getWidth()/2, paint);
}

public void onTouchEvent(MotionEvent event) {
    Log.v(TAG, "received touch event..");
}

}

我现在遇到的问题:

  • 当我按下主页按钮并重新输入应用程序或旋转我的设备时,它会调用surfaceDestroyed()但之后不会重新创建它(画布没有重新绘制)
  • 游戏渲染线程永不停止(如日志消息所示)

0 个答案:

没有答案