Camera.startPreview дает сбой и перезагружает телефон после нескольких запусков Activity - PullRequest
4 голосов
/ 19 января 2012

У меня есть Activity, который открывает Camera и запускает предварительный просмотр на SurfaceTexture. Все работает нормально, но я заметил, что если я несколько раз покидаю активность и возвращаюсь к ней, через несколько раз телефон зависает, а затем перезагружается.

Я сузил проблему до вызова startPreview. И я получаю два зловещих сообщения журнала прямо перед тем, как возникает проблема:

01-19 10:20:52.038: E/IMGSRV(22777): :0: __map: Map device memory failed
01-19 10:20:52.038: W/GraphicBufferMapper(22777): registerBuffer(0x70b750) failed -14 (Bad address)

Кто-нибудь видел это раньше? Это проблема с аппаратным обеспечением Galaxy Nexus или Android 4.0? Если да, есть ли обходные пути?

Примечание. Я проводил тестирование на Android 4.0 с Galaxy Nexus.

Правка - Решено:

Оказывается, это была утечка памяти из-за OpenGL. Все примеры в Интернете, которые я смог найти, используют следующий код для очистки после OpenGL.

try { mEgl.eglDestroyContext(mEglDisplay, mEglContext); } catch (Throwable t) {}
try { mEgl.eglDestroySurface(mEglDisplay, mEglSurface); } catch (Throwable t) {}

Это приводит к утечке поверхности, и в результате после некоторого количества попыток, которое варьируется в зависимости от телефона, OpenGL не сможет инициализироваться. Например, он потерпит неудачу после 32 попыток на Nexus S, но только 8 попыток на LG Optimus.

После некоторых проб и ошибок я обнаружил, что следующий код исправил проблему:

mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);

Примечание: на Galaxy Nexus вместо приятной ошибки OpenGL, которую я мог отобразить пользователю, она просто вылетала при startPreview. Я предполагаю, что это было связано с памятью, но вышеприведенное исправление также очистило его.

1 Ответ

2 голосов
/ 19 января 2012

Документы SDK для класса android.hardware.Camera говорят следующее:

Важно: Звоните release(), чтобы освободить камеру для использования другими Приложения. Приложения должны немедленно освободить камеру в onPause() (и повторно open() в onResume()).

Вы уверены, что ваша деятельность освобождает камеру в onPause() и повторно открывает ее в onResume()?

Если вы опубликуете пример кода, мы сможем решить вашу проблему.

...