android - Android SurfaceView onDraw暂停Thread.join()

标签 android multithreading join surfaceview ondraw

我正在尝试使用SurfaceView开发游戏。问题是,当我想使用thread方法销毁surfaceDestroyed()时,应用程序将停止在thread.join()中,但如果不这样做
canvas.drawColor(Color.GREEN);方法中绘制 Canvas (onDraw()),一切正常。
如何绘制 Canvas 并调用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) {
                }
            }
        }
    }
}

最佳答案

因此,我为这个问题提供的解决方案是更改其显示位置:

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);
        }
}

为了完成此 Activity 并调用另一个 Activity ,我添加了一种名为GameOver的方法,该方法效果很好:
private void GameOver() {
    gameLoopThread.setRunning(false);
    Context c = getContext();
    c.startActivity(intent); //intent must be declared
    ((Activity) Pruebas.this.getContext()).finish();
}

我希望这可以帮助别人。

关于android - Android SurfaceView onDraw暂停Thread.join(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15548319/

相关文章:

java - 如何在 Firestore 中存储富文本编辑器数据?

java - 如何获取设备网络信息? (安卓)

c# - 从事件处理程序在主线程中执行一个方法

Python多处理与多线程相结合

multithreading - C++ 0x中线程之间的异常传播

mysql - 具有右连接的 SQL View

java - 无法实例化 Activity ComponentInfo 空指针异常

android - Proguard 警告 "can' t 写入资源 [META-INF/MANIFEST.MF](重复的 zip 条目)”

PHP显示join查询结果

java - 如何使用 <join> 标记加入 hibernate 映射文件中的两列?