我想实现相机预览。为此,我有一个自定义视图CameraView extends ViewGroup
,它在构造函数中以编程方式创建一个表面视图。
我有以下组件(非常简化):
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() 上释放它)并且以下工作正常:
- 压家归来
- 按下 Taskswitcher 并返回
- 回转
- 压回(当然)
但是有一件事不起作用,那就是当我按下设备上的电源按钮然后返回相机预览时。结果是:预览卡在按下按钮之前最后捕获的图像上。如果我旋转它,它会再次正常工作,因为它将通过生命周期。
经过一番研究,我发现这可能是由于按下电源按钮时surfaceView不会被破坏,即SurfaceHolder.Callback.surfaceDestroyed(SurfaceHolder holder)
不会被调用。事实上,当我比较主页按钮盒和电源按钮盒的(非常详细的)日志输出时,除了不会调用“surfaceDestroyed”之外,它是相同的。
到目前为止,我没有找到任何解决方案来解决它。我故意避免在我的 中使用任何资源清理代码surfaceDestroyed()
,但这无济于事。我的想法是像在这个问题中提出的那样手动销毁surfaceView,但这似乎是不可能的。我还用 SurfaceViews/cameras 测试了其他应用程序,它们似乎没有这个问题。因此,我将不胜感激任何提示或提示。