Андроид:Восстановление фокуса с помощью SurfaceView
-
21-08-2019 - |
Вопрос
В настоящее время я осваиваю Android, экспериментируя с образцом Lunar Lander.
Я обнаружил, что если вы выйдете из приложения (например, нажмете кнопку вызова), оно разрушит основную поверхность (вызов surfaceDestroyed
).
Навигация назад (которая вызовет onWindowVisibilityChanged
) приложение выйдет из строя, так как оно попытается вывести изображение на поверхность, не создавая его заново.
Есть ли какой-нибудь код, который я могу ввести? onWindowVisibilityChanged
(или где-нибудь еще), который восстановит базовую поверхность SurfaceView и возобновит выполнение?
Такое ощущение, что это должен быть простой вызов функции, но я ничего не могу найти в документации API.
Спасибо!
Решение 2
Неправильный диагноз!Приложение автоматически воссоздает поверхность, но там есть вызов, который пытается выполнить отрисовку к ней до ее создания.
Устранение проблемы:
boolean mSurfaceExists;
...
public void surfaceDestroyed(SurfaceHolder holder) {
mSurfaceExists = false;
...
}
public void surfaceCreated(SurfaceHolder holder) {
mSurfaceExists = true;
...
}
protected void onWindowVisibilityChanged(int visibility) {
// only call base if there's a surface
if(mSurfaceExists)
super.onWindowVisibilityChanged(visibility);
}
Теперь все в порядке.(во всяком случае, насколько мне известно - эксперты по Java/Android не стесняются комментировать, если это плохая практика!)
Другие советы
Это решение для «mSurfaceExists = true» у меня тоже не работает.Похоже, поверхностьCreated() не вызывается, потому что super.onWindowVisibilityChanged() не вызывается.Таким образом, поверхность не создается и не происходит сбой, поскольку threas.start не вызывается.
Я считаю, что проблема в следующем:Вызов thread.start() вызывает ошибку, поскольку поток уже запущен.Но в функции SurfaceDestroyed() thread.join приводит к завершению и завершению потока.И поток не может быть перезапущен после смерти.
Я предполагаю, что хитрость заключается в том, чтобы создать новый поток в SurfaceCreated или заставить поток завершиться только тогда, когда пользователь вызывает приложение для завершения (клавиша возврата), а не приостановки (клавиша Home).Это можно проверить, вызвав isFinishing() для активности.
Не уверен, что это сработает.Я скоро попробую это.