【问题标题】:Android SurfaceView onDraw halts Thread.join()Android SurfaceView onDraw 停止 Thread.join()
【发布时间】:2013-03-11 00:13:55
【问题描述】:

我正在尝试使用SurfaceView 开发游戏。问题是,当我想用​​ surfaceDestroyed() 方法销毁 thread 时,应用程序会在 thread.join() 中停止,但如果不这样做 在onDraw() 方法中绘制画布(canvas.drawColor(Color.GREEN);)一切正常。 如何绘制画布并调用thread.join()??

(我测试了许多来自互联网的示例游戏,它们都有相同的问题,例如,当你点击返回按钮时,你会得到一个FATAL EXCEPTION,因为thread 仍在运行)

这是尽可能简单的代码。 谢谢

public class GameView extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder holder;
    private GameLoopThread gameLoopThread;

    public GameView(Context context) {
        super(context);
        holder = getHolder();
        holder.addCallback(this);
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        if (gameLoopThread == null) {
            gameLoopThread = new GameLoopThread(this);
            gameLoopThread.setRunning(true);
            gameLoopThread.start();
            Log.e("thread", "iniciado");
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        gameLoopThread.setRunning(false);
        boolean retry = true;
        while (retry) {
            try {
                gameLoopThread.join();
                retry = false;
            } catch (InterruptedException e) {
            }
        }
        Log.e("thread", "finalizado");
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.GREEN);
    }

    public static class GameLoopThread extends Thread {
        private static final int FPS = 20;
        private GameView view;
        private boolean running;

        public GameLoopThread(GameViwe gameView) {
            this.view = gameView;
        }

        public void setRunning(boolean run) {
            running = run;
        }

        @Override
        public void run() {
            long ticksPS = 1000 / FPS;
            long startTime;
            long sleepTime;
            while (running) {
                Canvas c = null;
                startTime = System.currentTimeMillis();
                try {
                    c = view.getHolder().lockCanvas();
                    synchronized (view.getHolder()) {
                        view.onDraw(c);
                    }
                } finally {
                    if (c != null) {
                        view.getHolder().unlockCanvasAndPost(c);
                    }
                }
                sleepTime = ticksPS - (System.currentTimeMillis() - startTime);
                try {
                    if (sleepTime > 0)
                        sleep(sleepTime);
                    else
                        sleep(10);
                } catch (Exception e) {
                }
            }
        }
    }
}

【问题讨论】:

    标签: android multithreading join surfaceview ondraw


    【解决方案1】:

    所以我对这个问题给出的解决方案是改变它所说的:

    try {
        c = view.getHolder().lockCanvas();
        synchronized (view.getHolder()) {
            view.onDraw(c);
        }
        } finally {
            if (c != null) {
               view.getHolder().unlockCanvasAndPost(c);
            }
    }
    

    在 GameLoopThread 类的 run() 方法上:

    try {
        c = view.getHolder().lockCanvas();
        synchronized (view.getHolder()) {
            if(c != null)
                view.onDraw(c);
        }
        } finally {
            if (c != null) {
               view.getHolder().unlockCanvasAndPost(c);
            }
    }
    

    为了完成这个活动并调用另一个活动,我添加了一个名为 GameOver 的方法,效果很好:

    private void GameOver() {
        gameLoopThread.setRunning(false);
        Context c = getContext();
        c.startActivity(intent); //intent must be declared
        ((Activity) Pruebas.this.getContext()).finish();
    }
    

    我希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2011-09-19
      • 2011-09-09
      • 2011-08-04
      • 2013-08-27
      • 1970-01-01
      • 1970-01-01
      • 2014-03-07
      • 1970-01-01
      • 2015-02-12
      相关资源
      最近更新 更多