安卓相机预览画面切换到后台,再切换前台预览画面卡住问题

前言:相机应用预览界面切换到后台后,通常会释放相机资源,这样其他应用能够及时打开摄像头。我的做法是在Acitivity生命周期的onStart()时打开摄像头,在onStop()释放摄像头资源。这样做存在一个小问题,预览界面切换后台再切前台,此时预览画面卡住。

原因:onStop()时,SurfaceView或TextureView没有销毁,所以重新打开摄像头时,view的生命周期不会重新执行,也就无法刷新。

解决方法:SurfaceView或TextureView通过new实例化,而不是在布局中定义。并且在onStart() 通过addview方式把view加到布局中,在onStop()时通过removeView()方式移除view。

具体实现,布局定义layout/activity_main.xml:

<?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" >

    <LinearLayout
        android: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>

 Activity中

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);
}

    @Override
    protected void onStart() {
        super.onStart();
        textureViewParent.addView(textureView);
        openCamera(textureView, 0);
    }

    @Override
    protected 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() {
            @Override
            public 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);
                }
            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
            }


        });
	}

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页