我正在尝试在 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
表示 Activity 处于前台并且游戏应该正在运行时的状态。
STATE_PAUSED
表示另一个活动进入前台时的状态。我不完全确定为什么在暂停时仍需要绘制,但这似乎是我从LunarLander 示例中收集到的。
我希望在我查看活动时,游戏会更新和绘制(我使用 LogCat 进行测试)。然后当我返回主屏幕或顶部出现另一个活动时,它只会绘制。
好吧,它确实在我观看活动时绘制和更新,因此游戏循环本身可以工作。但是当我离开活动时,它没有任何效果。这是从活动的 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);
}
}
}
如您所见,为了测试此方法,我记录了一些消息。现在,当我离开活动时,我发现“这里”已记录,但“那里”没有。现在,由于我对线程的了解有限(我几乎不知道synchronized
实际上是做什么的),我相信这会发生,因为我的线程无法与表面保持器同步。但我不知道为什么它不同步。离开活动几秒钟后,我在 LogCat 中看到以下警告:
Activity pause timeout for HistoryRecord
知道为什么会发生这种情况吗?如果我再次尝试启动 Activity 没有问题,线程会保持原样运行。
非常感谢。
编辑:刚刚发现了别的东西。如果我在启动活动后大约一秒钟内离开活动,线程就会暂停。然后它将在同一任务仍在运行时再次恢复并暂停,完全没有问题。我不知道为什么在短时间内它会起作用,但如果我离开它太久,它就不会了。
编辑2:好的......我修好了。但我不认为我应该做我做过的事。我基本上已经mSurfaceHolder
从 pause() 和 setState() 方法(由 pause() 使用)中删除了任何同步。不,它按预期工作,但我认为同步是有原因的。
也许对我来说最好的问题是:何时应该使用同步块将线程与对象同步?而在这种情况下,与 SurfaceHolder 同步的目的是什么?