Поток пользовательского интерфейса Android заблокирован в новом действии

StackOverflow https://stackoverflow.com//questions/24003919

Вопрос

Я работаю над небольшой игрой для Android, которая обрабатывает рисование на холсте в рабочем потоке.После окончания игры этот поток должен запустить следующее действие, но каким-то образом поток пользовательского интерфейса, похоже, блокируется при запуске новой функции.

Это основной цикл моих игр:

while(true)
    // Perform Ticks until the player makes a mistake
    c = _surfaceHolder.lockCanvas();
    if ((toDraw = rh.performTick()) == null) {
         lose();
         break;
     }
     _surfaceHolder.unlockCanvasAndPost(draw(toDraw,c));
}

Функция performTick() обрабатывает логику игры и возвращает null когда игра закончится. draw()выполняет рендеринг.Обе функции работают идеально - проблема в том, что lose(), который ничего не делает , кроме как начинает новое действие:

    protected void lose() {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(_context, MainMenu.class);
                _context.startActivity(intent);
            }
        });
    }

Когда игра заканчивается, новая активность (главное меню) запускается нормально, но не реагирует ни на какие сенсорные события.Нет выходных данных LogCat и не возникает исключений.Еще хуже, lose()работает нормально, когда он вызывается перед запуском основного цикла.

Я работаю над этим уже несколько дней.Я попытался запустить действие непосредственно из рабочего потока (без использования Handler в lose()) и часами рылся в Интернете - ничего не помогает.Похоже, что поток пользовательского интерфейса каким-то образом заблокирован или попал в бесконечный цикл, и я понятия не имею, как это исправить.

Все отлажено на устройстве Nexus 4.

Кстати: MainMenu.onCreate() работает нормально, когда запущен другим способом.

Пожалуйста, помогите, MA3o

Это было полезно?

Решение

Вы не разблокируете холст, когда оператор if имеет значение true.Перерыв выведет вас из состояния ожидания, оставив холст заблокированным.

while(true)
    // Perform Ticks until the player makes a mistake
    c = _surfaceHolder.lockCanvas();
    if ((toDraw = rh.performTick()) == null) {
         lose();
         break;
     }

     // this line won't be executed whether the if statement above is true
     _surfaceHolder.unlockCanvasAndPost(draw(toDraw,c));
}

Вы также должны разблокировать внутри оператора if (до или после lose()).

Другие советы

Вместо этого, если While(true) ты мог бы While(myVar) где myVar это логическое значение, которое имеет значение true, пока игра должна быть запущена, и устанавливается в значение false при вызове lose() В вашем случае вы продолжали рисовать, хотя в этом не было необходимости.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top