Я пытаюсь написать игровой движок для 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 .
Я надеюсь, что пока яСмотрю на активность, игра обновится и нарисует (что я тестирую с помощью LogCat).А потом, когда я возвращаюсь на домашний экран или на экране появляется другое действие, оно просто нарисует.Сам игровой цикл работает.Но когда я оставляю активность, это не имеет никакого эффекта.Вот метод потока pause (), который вызывается из функции onPause ():
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
Есть идеи, почему это может произойти?Нет проблем, если я снова попытаюсь запустить упражнение, поток просто продолжит работать, как и было.
Большое спасибо.
РЕДАКТИРОВАТЬ : Просто обнаружил что-то еще,Поток приостанавливается, если я оставляю активность примерно через секунду после ее запуска.И затем он возобновится и снова остановится без проблем, пока та же задача еще выполняется.Я понятия не имею, почему в течение короткого периода времени это будет работать, но если я оставлю это слишком долго, это не будет.
РЕДАКТИРОВАТЬ 2 : Хорошо ... Я исправил это,Но я не думаю, что я должен делать то, что я сделал.Я в основном удалил любую синхронизацию с mSurfaceHolder
из методов pause () и setState () (которая используется pause ()).Нет, это работает так, как и должно, но я думаю, что причина синхронизации есть.
Возможно, лучший вопрос, который мне нужно задать, это: КОГДА следует синхронизировать поток с объектом с помощьюсинхронизированный блок?И в этом случае, какова цель синхронизации с SurfaceHolder?