One of the official Google samples for the Camera2 API遭遇the same BufferQueue has been abandoned
problem,如下所示:
具体来说,示例应用从closeCamera()
片段调用onPause()
方法,其中closeCamera()
在close()
上调用CameraCaptureSession
,然后{{1在close()
上,然后CameraDevice
上的close()
(用于实际拍照)。 ImageReader
上的close()
是在LogCat中出现上述CameraDevice
消息的几次后,虽然我只在某些Android 5.1硬件上获得该消息(Nexus 4和Nexus 7 2013)而不是其他人(Nexus 5和Nexus 6)。
fadden对此的评论是:
如果在进入onPause()之前关闭了消费者方,则会发出消息。
何时BufferQueue has been abandoned
的“消费者方面”会被关闭,为什么呢?
Google的示例代码不会主动执行任何操作来关闭我能看到的TextureView
。而且,由于TextureView
在暂停时仍然可见,我原本预计“消费者方面”不会在TextureView
时受到影响,但可能会在onPause()
之后受到影响。
虽然我意识到这条消息(尽管是一个错误)是良性的,但我正试图弄清楚如何摆脱它,如果没有其他原因而不是阻止我一次又一次地被问到为什么我的代码正在记录此错误。我希望通过更多地了解这个“消费者方面”,我可以弄清楚当用户退出使用Camera2的活动或片段时如何更好地整理一下并避免这个错误。
答案 0 :(得分:3)
在退出onPause之前,您是否在等待调用相机的onClosed状态回调方法?
在回调触发之前,相机可能仍有未完成的工作要做,而close()的定义是在关闭设备之前完成所有待处理的捕获请求。这可以通过在调用close()之前调用abortCapture()来加速。
某些设备(如N5和N6)当前阻止了close()调用,因此当它返回时,所有待处理的工作都已完成,但这是一个实现细节,我认为我们的示例无意中依赖于今天。
但是,我们通常希望允许应用程序立即调用close()并保留onPause(),以避免在等待相机硬件关闭时挂起UI线程。但今天这还不是现实。
换句话说,close()应该是异步的,并不在所有设备上。但是我们希望你可以解雇并忘记它,所以这些错误信息需要在摄像机设备一侧解决(当重复请求目标在操作中间消失时,不会发送垃圾邮件)。
今天不建议只调用close()和退出onPause()的另一个原因是它会阻止其他应用打开 onResume()调用中的相机,在相机应用程序之间切换时会导致虚假错误。
总结一下:
目前:在调用CameraDevice#close()之后退出onPause()之前等待CameraDevice.StateCallback#onClosed被调用。
在未来的某个时刻:只需调用close()并退出onPause即可。该框架将正确地允许下一个应用程序连接,而不是垃圾邮件您的日志。对不起,这不是今天的状态!
答案 1 :(得分:1)
关于实际问题 - "什么时候是TextureView'消费者方面'关闭",我不知道确切的时间,但肯定是在onPause返回后。
粗略地说,TextureView包含一个GL表面,一旦活动的UI不再可见,那些资源就会被拆除。一旦发生这种情况,TextureView发出的SurfaceTexture就不再有效了,SurfaceTexture的任何现有用户(或由它制作的Surfaces)都会开始接收这些错误。在此之前,TextureView应调用方法TextureView.SurfaceTextureListener.onSurfaceTextureDestroyed。
作为替代方案,您可以从onSurfaceTextureDestroyed返回false以避免在UI拆卸期间释放它,而是等待onClosed触发,然后在onClosed中自行释放TextureView的SurfaceTexture。但是,我对UI / View方面的知识不太熟悉,以确保这一点可以正常工作,并且由于某些底层本机表面以任何一种方式发布,您可能仍会看到遗弃的错误用这种方法。
如果您有好奇心,相关代码的最高级别位于TextureView,尤其是destroySurface方法,尽管您需要了解整个Android UI系统,用于解析何时调用destroySurface方法及其效果。