【相机开发问题总结】后台恢复到前台预览界面卡住
问题描述
页面提供了相机预览功能,该页面有可能长时间活跃在前台,也有可能偶尔被语音或者其他操作顶到后台去。
回到后台时,需要释放相机资源。
回到前台时,需要恢复相机资源和预览界面。
恢复的过程,出现界面卡顿的问题。
问题分析
onStop()时,SurfaceView或TextureView没有销毁
所以重新打开摄像头时,view的生命周期不会重新执行,也就无法刷新。
问题解决
surfaceView或TextureView通过new实例化,而不是在布局中定义。并且在onStart() 通过addview方式把view加到布局中,在onStop()时通过removeView()方式移除view。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent" ><LinearLayoutandroid:id="@+id/preview_parent"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><!-- add or remove textureview on activity--></LinearLayout><!-- others view --></RelativeLayout>
动态创建view
private TextureView textureView;
private LinearLayout textureViewParent;
private Camera camera;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textureViewParent = findViewById(R.id.preview_parent);textureView = new TextureView(this);LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);textureView.setLayoutParams(lp);
}@Overrideprotected void onStart() {super.onStart();textureViewParent.addView(textureView);openCamera(textureView, 0);}@Overrideprotected void onStop() {super.onStop();textureViewParent.removeView(textureView);if (camera != null) {camera.stopPreview();camera.setPreviewCallback(null);camera.release();}}private void openCamera(final TextureView textureView, final int cameraId) {if (textureView == null || cameraId < 0) {return;}textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {try {camera = Camera.open(cameraId);camera.setPreviewTexture(surfaceTexture);camera.startPreview();} catch (IOException localIOException) {Log.e(TAG, "onSurfaceTextureAvailable open camera localIOException cameraId=" + cameraId + ", error=" + localIOException.getMessage(), localIOException);} catch (Exception e) {Log.e(TAG, "onSurfaceTextureAvailable open camera cameraId=" + cameraId + ", error=" + e.getMessage(), e);}}@Overridepublic void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {}@Overridepublic boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {return false;}@Overridepublic void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {}});}