我们是一组开发人员,他们正在为 Android 开发实时视频处理应用程序。最近,一位客户报告说我们的应用程序冻结了,这种情况仅发生在 Nexus 10 设备上。我们自己购买了设备并进行了测试:
- 设备预装了 Android 4.2 - 我们的应用程序没有挂起或冻结
- 将Android升级到4.3后,我们的应用程序在关闭相机时冻结(解释见下文)
- 通过升级到 4.4,我们的应用程序一直冻结
- 通过刷新最新的 Android 5.0 Nexus 10 出厂镜像,我们的应用仍然卡住
- (编辑) - 通过将 Nexus 10 升级到 Android 5.1 解决了问题
有关冻结的更多信息:
我们的应用程序在活动的 onResume 方法中打开相机,安装预览回调,将预览大小设置为最适合我们的处理需求(在 nexus 10 上,这是 1920x1080)并启动预览(如果从睡眠中恢复)或委托相同到 SurfaceView 回调的 surfaceCreated 方法。在 onPause 方法中,我们的应用程序删除了预览回调,停止了相机预览并释放了相机。但是,我们的调查表明,该camera.release
方法有时需要 30 秒才能完成。在那 30 秒内,我们的应用程序被冻结,因为我们曾经从 UI 线程控制相机。后来我们将相机控件移动到单独的事件处理程序线程,现在camera.release
挂起那个线程。虽然这对用户来说现在是不可见的(UI 没有被阻塞),但用户不能从任何应用程序使用相机,直到我们的后台线程成功释放相机(即camera.release
调用后 30 秒)。
在挂起期间,我们观察到相机服务的以下日志输出:
10-21 16:08:54.193: E/Camera2-Device(122): waitUntilDrained: Waited 10050000 us, 2 requests still in flight
10-21 16:08:54.193: E/Camera2Client(122): stopPreviewL: Camera 0: Waiting to stop streaming failed: Connection timed out (-110)
10-21 16:09:04.293: E/Camera2-Device(122): waitUntilDrained: Waited 10050000 us, 2 requests still in flight
10-21 16:09:04.293: E/Camera2Client(122): stopPreviewL: Camera 0: Waiting to stop streaming failed: Connection timed out (-110)
10-21 16:09:14.453: E/Camera2-Device(122): waitUntilDrained: Waited 10050000 us, 2 requests still in flight
10-21 16:09:14.453: E/Camera2-StreamingProcessor(122): deletePreviewStream: Error waiting for preview to drain: Connection timed out (-110)
10-21 16:09:24.573: E/Camera2-Device(122): waitUntilDrained: Waited 10050000 us, 2 requests still in flight
10-21 16:09:24.573: E/Camera2-CallbackProcessor(122): deleteStream: Error waiting for HAL to drain: Connection timed out (-110)
10-21 16:09:24.578: E/libexynosv4l2(122): failed to ioctl: VIDIOC_REQBUFS (-1 - Invalid argument)
10-21 16:09:24.578: E/ExynosCameraHAL2(122): cam_int_reqbufs: VIDIOC_REQBUFS (fd:35) failed (-1)
10-21 16:09:24.843: E/Camera2-CallbackProcessor(122): deleteStream: Camera 0: Device does not exist
10-21 16:09:24.853: E/Camera2-StreamingProcessor(122): deletePreviewStream: Camera 0: Device does not exist
您可以在此处看到触发此行为的最小示例- 需要快速重新启动相机活动几次以增加进入此状态的机会。我们注意到它在我们的应用程序中比在示例应用程序中更频繁地发生。我们的应用程序进行了一些繁重的帧处理,还使用 GPU 进行图像处理,除了相机还使用加速度计和方向传感器 - 所有这些都不包含在示例应用程序中。
我们还看到了几个关于同一问题的未回答的 StackOverflow 问题(问题 1和问题 2)。您能否解释一下什么代码路径会导致提到的日志输出以及如何避免进入该状态?
到目前为止,我们没有在任何其他设备上遇到上述相机冻结。