【问题标题】:SurfaceView for Camera Preview won't get destroyed when pressing Power-Button按下电源按钮时,相机预览的 SurfaceView 不会被破坏
【发布时间】:2013-11-03 21:51:07
【问题描述】:

我想实现相机预览。为此,我有一个自定义 View CameraView extends ViewGroup,它在构造函数中以编程方式创建了一个 surfaceView。

我有以下组件(非常简单):

ScannerFragment.java

public View onCreateView(..) {
   //inflate view and get cameraView
}

public void onResume() {
   //open camera -> set rotation -> startPreview (in a thread) -> 
   //set preview callback -> start decoding worker
}

public void onPause() {
   // stop decoding worker -> stop Preview -> release camera
}

CameraView.java 扩展 ViewGroup

public void setUpCalledInConstructor(Context context) {
   //create a surfaceview and add it to this viewgroup ->
   //get SurfaceHolder and set callback
}

/* SurfaceHolder.Callback */
public void surfaceCreated(SurfaceHolder holder) {
   camera.setPreviewDisplay(holder);
}

public void surfaceDestroyed(SurfaceHolder holder) {
    //NOTHING is done here
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    camera.getParameters().setPreviewSize(previewSize.width, previewSize.height);
}

fragment_scanner.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.myapp.camera.CameraView
        android:id="@+id/cameraPreview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

我认为我已经正确设置了生命周期(获取资源 onResume(),释放它 onPause() 粗略地说)并且以下工作正常:

  • 按 Home 并返回
  • 按下任务切换器并返回
  • 旋转
  • (当然)压回

但有一件事不起作用,那就是当我按下设备上的电源按钮然后返回相机预览时。结果是:预览卡在按下按钮之前最后捕获的图​​像上。如果我旋转它,它会再次正常工作,因为它会通过生命周期。

After some research我发现这可能是由于按下电源按钮时surfaceView不会被破坏,即SurfaceHolder.Callback.surfaceDestroyed(SurfaceHolder holder)不会被调用。事实上,当我比较 home-button-case 和 power-button-case 的(非常详细的)日志输出时,除了不会调用“surfaceDestroyed”之外,它是相同的。

到目前为止,我没有找到任何解决方案来解决它。我故意避免在我的surfaceDestroyed() 中使用任何资源清理代码,但这无济于事。我的想法是manually destroy the surfaceView like asked in this question,但这似乎是不可能的。我还用 SurfaceViews/cameras 测试了其他应用程序,它们似乎没有这个问题。因此,我将不胜感激任何提示或提示。

【问题讨论】:

  • 回顾一下:问题是应用程序生命周期中的错误。基本上一些 onCreate/onResume 错过了特定情况下所需的一些设置。

标签: java android android-camera surfaceview activity-lifecycle


【解决方案1】:

尝试添加

 public void onDestroy() {
 // stop decoding worker -> stop Preview -> release camera
}

正如对 onPause() 所做的那样,因为它可能会被调用,只要 pause 方法。

在我的 releaseCamera() 中我就是这样做的

    private void releaseCamera() {
    if (myCamera != null) {
        FrameLayout preview = (FrameLayout) findViewById(R.id.cameraPreview);
        preview.removeView(myPreview);
        myCamera.setPreviewCallback(null);
        myCamera.release();
        myCamera = null;

    }
}

我分离了 CameraPreview (myPreview),它保存了当前图片。并完全摧毁相机。

【讨论】:

  • 问题不是我的停止/销毁代码没有被调用,而是我没有任何选择手动销毁surfaceview,因为它应该自己销毁
【解决方案2】:

mPreview.getHolder().removeCallback(mPreview);应该帮忙吗?

【讨论】:

    猜你喜欢
    • 2012-01-05
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 2014-04-25
    相关资源
    最近更新 更多