暂停线程 - HistoryRecord的活动暂停超时

时间:2010-06-30 13:43:45

标签: android multithreading android-activity game-loop

我正在尝试在Android中编写游戏引擎,但我对线程并不太熟悉。

我的主题有一个属性mSurfaceHolder,它保存了我将要绘制的表面。我的线程的run()方法如下所示:

public void run() {
    // We're running now
    setState(STATE_RUNNING);

    // Keep looping while the game is running or paused
    while (mState == STATE_RUNNING || mState == STATE_PAUSED) {
        synchronized (mSurfaceHolder) {
            // If the game is running, update physics etc.
            if (mState == STATE_RUNNING) {
                updateGame();
            }
            // Draw the game even if it's paused
            drawGame();
        }
    }
}

STATE_RUNNING表示活动在前台并且游戏应该运行时的状态。 STATE_PAUSED表示另一个活动进入前台时的状态。我不完全确定为什么我需要在它暂停时仍然绘制,但这就是我似乎从LunarLander example收集的内容。

我希望在观看活动时,游戏会更新并绘制(我使用LogCat进行测试)。然后,当我回到主屏幕或其他活动出现在顶部时,它将只是绘制。

当我正在观看活动时, 进行绘制和更新,因此游戏循环本身有效。但是当我离开活动时,它没有任何效果。这是从activity的onPause()调用的线程的pause()方法:

public void pause() {
    Log.d("Game","Here");
    synchronized (mSurfaceHolder) {
        Log.d("Game","There");
        // If the thread is running, pause it
        if (mState == STATE_RUNNING) {
            setState(STATE_PAUSED);
        }
    }
}

如您所见,为了测试此方法,我记录了一些消息。现在我离开活动时发现的是“Here”被记录,但“There”没有。由于我对线程知识有限(我几乎不知道synchronized实际上做了什么),我相信这会发生,因为我的线程无法与表面持有者同步。但我不知道为什么它不同步。离开活动几秒钟后,我在LogCat中看到以下警告:

Activity pause timeout for HistoryRecord

知道为什么会这样吗?如果我尝试再次启动活动没有问题,线程会保持原样运行。

非常感谢。

编辑:刚刚发现其他内容。如果我在启动它的大约一秒钟内离开活动,该线程会暂停。然后,当同一任务仍在运行时,它将恢复并暂停,完全没有任何问题。我不知道为什么它会在短时间内发挥作用,但是如果我把它留下太久,它就不会。

编辑2 :好的......我修好了。但我不认为我应该做我做过的事情。我基本上从pause()和setState()方法(暂停()使用)中删除了与mSurfaceHolder的任何同步。不,它应该按预期工作,但我认为同步是有原因的。

也许对我来说最好的问题是: 什么时候应该使用synchronized块同步线程与对象?在这种情况下,与SurfaceHolder同步的目的是什么?

1 个答案:

答案 0 :(得分:3)

Java中的synchronize关键字确保两个线程不能同时触及同一个对象,从而防止竞争条件。换句话说,它实现了锁定。

最有可能的是,你在这里遇到了僵局。另一个线程可能正在使用mSurfaceHolder,因此持有此对象的锁。 synchronized (mSurfaceHolder)中的代码将阻塞,直到其他线程完成,这显然没有发生。

但是,由于您实际上并没有以任何方式修改mSurfaceHolder,因此没有理由对其进行锁定。您唯一需要记住的是,在调用时间pause()和更新它的值之间可能会读取mState。如果这是一个问题,请在mState上进行同步。