Camera.startPreview 在多次运行 Activity 后崩溃并重新启动手机

发布于 12-27 16:40 字数 1187 浏览 2 评论 0原文

我有一个 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 无法初始化。例如,在 Nexus S 上尝试 32 次后就会失败,但在 LG Optimus 上只尝试 8 次。

经过一番尝试和错误后,我发现以下代码解决了该问题:

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

注意:在 Galaxy Nexus 上,我没有得到一个很好的 OpenGL 错误(我可以向用户显示该错误),但它似乎在 startPreview 上崩溃了。我认为这与内存有关,但上面的修复也清除了它。

I have an Activity that opens the Camera and starts a preview on a SurfaceTexture. Everything works fine, but I've noticed that if I repeatedly leave the activity and return to it, after a handful of times, the phone freezes and then reboots.

I've narrowed the problem down to the call to startPreview. And I get two ominous log messages right before the issue happens:

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)

Has anyone seen this before? Is this an issue with the Galaxy Nexus hardware or Android 4.0? If so, are there any work arounds?

Note: My testing is on Android 4.0, with a Galaxy Nexus.

Edit - Solved:

Turns out it was a memory leak due to OpenGL. All the examples on the web I could find use the following code to clean up after OpenGL.

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

This leaks the surface, and as a result after some number of tries, which varies per phone, will cause OpenGL to fail to initialize. For instance it would fail after 32 tries on the Nexus S, but only 8 tries on the LG Optimus.

After some trial and error I found that the following code fixed the issue:

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

Note: On the Galaxy Nexus instead of getting a nice OpenGL error which I could display to the user it just seemed to crash on startPreview. I assume this was memory related, but the above fixed cleared it up as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

灼疼热情2025-01-03 16:40:17

android.hardware.Camera 类的 SDK 文档 说明如下:

重要:调用release()释放相机以供其他人使用
应用程序。应用程序应立即释放相机
onPause()(并在 onResume() 中重新open())。

您确定您的 Activity 在 onPause() 中释放相机并在 onResume() 中重新打开它吗?

如果您发布代码示例,我们将能够更好地解决您的问题。

The SDK docs for the android.hardware.Camera class say the following:

Important: Call release() to release the camera for use by other
applications. Applications should release the camera immediately in
onPause() (and re-open() it in onResume()).

Are you certain your activity releases the camera in onPause() and re-opens it in onResume()?

If you post a code sample, we would be better able to troubleshoot your problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文