Исключение Android IllegalThreadStateException в LunarLander
-
22-08-2019 - |
Вопрос
Просто приходите к полировке моего приложения и возобновлению его работы после ухода пользователя.Когда приложение восстанавливается, я получаю исключение IllegalThreadStateException, что довольно раздражает.Эта проблема присутствует в примере, который Google приводит Лунный посадочный модуль.Кто-нибудь нашел способ восстановить работу при использовании SurfaceView?
Решение
Я полагаю, что это происходит из-за несоответствия в том, как обрабатываются Поверхность и Активность.Когда вы покидаете приложение LunarLander, поверхность уничтожается (вызывается surfaceDestroyed), но Действие только приостанавливается (вызывается onPause).Когда действие возобновляется, создается поверхность (вызывается surfaceCreated), и она пытается снова запустить поток рисования.
Это означает, что создание потока происходит с жизненным циклом Activity, а уничтожение потока происходит с жизненным циклом SurfaceView, которые не всегда соответствуют, таким образом, возникает исключение IllegalThreadStateException .Решением было бы привязать поток к одному жизненному циклу или другому, а не к обоим.
Я думаю, что этот поток предлагает возможное решение, хотя я не знаю, работает ли оно.
Другие советы
В моем собственном тесте я создаю поток рисования в методе surfaceCreated(), и это полностью решает проблему.Это реализация моего метода:
@Override
public void surfaceCreated(SurfaceHolder arg0) {
_thread = new DrawThread(getHolder());
_thread.setRunning(true);
_thread.start();
}
Итак, в коде, когда surfaceDestroyed()
вызывается, оно устанавливает mRun
к ложному и вызывает thread.join()
.Это приводит к завершению потока и его завершению.Когда приложение будет запущено снова и surfaceCreated()
вызывается, оно вызывает thread.start()
.Это недопустимо, потому что поток не может быть запущен после его завершения.
Два варианта исправления:
а) Запустите новый поток в surfaceCreated()
- как указано выше.
б) Или добавить проверку в surfaceDestroyed()
против Activity.isFinishing()
завершать поток только в том случае, если true .Чтобы сделать это, я окружил while(mRun)
в потоке с другим циклом while, для которого установлено значение false только в том случае, если isFinishing()
возвращает значение true.