понедельник, 9 декабря 2013 г.

Android SDL2 crash on lock

В процессе написания игры под андроид с использованием SDL2 всплыла следующая ошибка. Периодически игра не хотела запускатсья или восстанавливаться, показывая чёреный экран. Ошибка воспроизводится при использовании дефолтного манифеста. Если во время игры нажать кнопку блокировки, то у SDL activity вызовется onDestroy(), что приведёт к завершению всего приложения и остановке потока нативного кода. Вот только вместо обычного события завершения
SDL_QUIT
вам придёт
SDL_APP_TERMINATING
Лично я до встречи с этой проблемой о таком событии вообще ничего не слышал и в документации не встречал. Поэтому корректно это событие не обрабатывалось, окно и рендер не удалялись, OpenGL контекст не закрывался и при разблокировке приложение не могло запуститься вновь.
Выхода два: обрабатывать событие как завершение приложения или вообще не закрываться при блокировке. Первый вариант не удачен, потому что это ломает парадигму использования андроидом. После разблокировки приложение должно продолжить работу. Поэтому нам надо чтобы onDestroy у активити вообще не вызывался. По этому поводу идём на stackoverflow и добавляем в манифест:
android:configChanges="orientation|keyboardHidden|screenSize"
Всё, теперь приложение будет продолжать работу, не обращая внимания на блокировку экрана.

Для англоязычных коллег / For English speaking programmers

My android SDL2 game crashed sometimes and showed black screen. If user press lock button onDestroy() method called and instead of
SDL_QUIT
event
SDL_APP_TERMINATING
event was sent to native code. I didn't know about this event because there is no any notes in documentation about it. So this event wasn't processed and renderer wasn't destroyed on application quit. You can process this event and exit correctly or add
android:configChanges="orientation|keyboardHidden|screenSize" 
 to android manifest to prevent onDestroy() method call. This solution was found at stackoverflow.