【问题标题】:Releasing the camera: "Method called after release()" exception释放相机:“释放()后调用的方法”异常
【发布时间】:2014-10-08 14:06:49
【问题描述】:

我正在尝试在我的应用中加入一些与相机相关的功能。我手动打开相机并使用setPreviewCallbackstartPreview 获取预览流。我确实使用表面来显示预览,但我确实将其设置为符合相机 API 文档。这就是我打开相机的方式:

public Camera openCamera(int id)
{
    m_openedCamera = Camera.open(id);
    m_surfaceHolder = new SurfaceView(MyApplication.instance().getApplicationContext()).getHolder();
    Assert.assertNotNull(m_openedCamera);
    m_openedCamera.setPreviewDisplay(m_surfaceHolder);
    m_openedCameraFacing = facing;
    if (m_openedCamera != null)
        m_openedCamera.setPreviewCallback(this);
    m_openedCamera.startPreview();
}

这就是我发布它的方式,这里没什么特别的:

public void releaseCamera()
{
    if (m_openedCamera != null)
    {
        m_openedCamera.stopPreview();
        m_openedCamera.release();
        m_openedCamera = null;
    }
}

一开始还可以,但是当我释放相机时,我得到一个异常“释放()之后调用的方法”。 澄清一下:我确实在相机发布后调用任何相机方法。在我没有的调试器下进行双重和三重检查。我认为这里混合了同步和异步调用会导致问题。

【问题讨论】:

  • checkout this 如果有帮助,如果您按照答案中的说明在代码中添加mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);,问题可能会得到解决。
  • @MehulJoisar:请仔细阅读我的问题,并意识到我没有任何表面或支架。
  • 不使用预览表面(或其 OpenGL 等效项)是非法的,并且可能会在不同的设备上导致不同的问题。如果我理解正确,您的目的是从后置摄像头切换到前置摄像头。请理解,这两种不同的设备可能以不同方式处理此密钥
  • @AlexCohn:不一定要切换,现在我正在使用同一台相机。但是,是的,主要目的是切换相机。另外,我认为你错了,文档没有说我必须使用显示表面。那只是一个方便的帮手。我的应用中不需要它。
  • 当然可以。在 3.0 及更高版本上,使用 setPreviewTexture() 更容易实现。 this SO topic 中有一长串 hacks 解决方法。

标签: android camera android-camera


【解决方案1】:

预览回调可能会导致此异常。 onPreviewFrame() 不同步,它接收到一个Camera 参数,执行Camera.release() 时可能会失效。即使回调没有使用单独的线程(强烈推荐),也可能发生这种情况。

release()之前,调用setPreviewCallback(null),并保留一个全局标志以丢弃相机释放后的回调。

【讨论】:

  • 您为相机回调推荐了一个单独的线程,我说对了吗?我怎么做?通过在单独的线程中初始化相机?
  • 是的,Camera.open() 来自 separate event thread
  • 感谢您的帮助!
猜你喜欢
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多