Android 释放相机:“释放()后调用的方法”异常

Android 释放相机:“释放()后调用的方法”异常,android,camera,android-camera,Android,Camera,Android Camera,我正在尝试在我的应用程序中加入一些与相机相关的功能。我手动打开相机,使用setPreviewCallback和startPreview获取预览流。我不使用曲面显示预览,但我确实将其设置为符合摄影机API文档。这是我打开相机的方式: public Camera openCamera(int id) { m_openedCamera = Camera.open(id); m_surfaceHolder = new SurfaceView(MyApplication.instance(

我正在尝试在我的应用程序中加入一些与相机相关的功能。我手动打开相机,使用setPreviewCallback和startPreview获取预览流。我不使用曲面显示预览,但我确实将其设置为符合摄影机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;
    }
}
它一开始可以工作,但当我释放相机时,我得到一个异常方法,在释放后调用。
澄清一下:我不会在相机发布后调用任何相机方法。我没有在调试器下进行双重和三重检查。我认为同步调用和异步调用混合在一起会导致问题。

预览回调可能会导致此异常。onPreviewFrame不同步,它接收一个相机参数,该参数在执行Camera.release时可能会失效。即使回调未使用单独的线程,也可能发生这种情况。强烈建议使用单独的线程


在释放之前,调用setPreviewCallbacknull,并保留一个全局标志以在相机释放后放弃回调

预览回调可能导致此异常。onPreviewFrame不同步,它接收一个相机参数,该参数在执行Camera.release时可能会失效。即使回调未使用单独的线程,也可能发生这种情况。强烈建议使用单独的线程


在释放之前,调用setPreviewCallbacknull,并保留一个全局标志以在相机释放后放弃回调

签出如果有帮助,如果添加mHolder.setTypeSurfaceHolder.SURFACE\u TYPE\u PUSH\u缓冲区,问题可能会得到解决;“请仔细阅读我的问题,并意识到我没有任何曲面或支架。使用无预览曲面或其OpenGL等价物是非法的,可能会在不同的设备上导致不同的问题。”。如果我理解正确,您的目的是从后向摄像头切换到前向摄像头。请理解,这两种不同的设备可能会处理此密钥differently@AlexCohn:不必切换,现在我使用的是同一台相机。但是,是的,主要目的是切换摄像机。另外,我认为你错了,文档没有说我必须使用显示表面。那只是个方便的帮手。我的应用程序中不需要它。当然可以。在3.0及更高版本上,使用setPreviewTexture更容易实现。在中有一长串黑客解决方法。签出如果有帮助,如果添加mHolder.setTypeSurfaceHolder.SURFACE\u TYPE\u PUSH\u缓冲区,问题可能会得到解决;“请仔细阅读我的问题,并意识到我没有任何曲面或支架。使用无预览曲面或其OpenGL等价物是非法的,可能会在不同的设备上导致不同的问题。”。如果我理解正确,您的目的是从后向摄像头切换到前向摄像头。请理解,这两种不同的设备可能会处理此密钥differently@AlexCohn:不必切换,现在我使用的是同一台相机。但是,是的,主要目的是切换摄像机。另外,我认为你错了,文档没有说我必须使用显示表面。那只是个方便的帮手。我的应用程序中不需要它。当然可以。在3.0及更高版本上,使用setPreviewTexture更容易实现。这里有一长串的黑客解决方法。你推荐一个单独的摄像头回调线程,我做对了吗?我该怎么做?通过在单独的线程中初始化摄像头?是的,通过摄像头打开。感谢您的帮助!你推荐一个单独的摄像头回调线程,我做对了吗?我该怎么做?通过在单独的线程中初始化摄像头?是的,通过摄像头打开。感谢您的帮助!