【Android Camera1】Camera1初始化销毁流程(六) —— Camera1Impl类之startPreview,release

【Android Camera1】Camera1初始化销毁流程(六) —— Camera1Impl类之startPreview,release,第1张

【Android Camera1】Camera1初始化销毁流程(六) —— Camera1Impl类之startPreview,release

startPreview,release
  • 一、摘要
  • 二、伪代码
    • 2.1 Camera1源码
    • 2.2 官方Demo
    • 2.3 更新代码
    • 2.4 releaseCamera

一、摘要

本篇文章包含如下2个部分:

  • startPreview
  • release
二、伪代码 2.1 Camera1源码

Camera.java源码里startPreview描述如下:

    
    public native final void startPreview();

分析

  1. Starts capturing and drawing preview frames to the screen
  2. 需要提供SurfaceTexture或者SurfaceHolder才可preview
  3. setPreviewCallback可监听preview的状态
  4. 会抛异常。
2.2 官方Demo

官方Demo里startPreview的相关逻辑如下:

  Camera1(Callback callback, PreviewImpl preview) {
      super(callback, preview);
      preview.setCallback(new PreviewImpl.Callback() {
          @Override
          public void onSurfaceChanged() {
              if (mCamera != null) {
                  setUpPreview();
                  adjustCameraParameters();
              }
          }
      });
  }
    
  @Override
  boolean start() {
      chooseCamera();
      openCamera();
      if (mPreview.isReady()) {
          setUpPreview();
      }
      mShowingPreview = true;
      mCamera.startPreview();
      return true;
  }
  
  // Suppresses Camera#setPreviewTexture
  @SuppressLint("NewApi")
  void setUpPreview() {
      try {
          if (mPreview.getOutputClass() == SurfaceHolder.class) {
              mCamera.setPreviewDisplay(mPreview.getSurfaceHolder());
          } else {
              mCamera.setPreviewTexture((SurfaceTexture) mPreview.getSurfaceTexture());
          }
      } catch (IOException e) {
          throw new RuntimeException(e);
      }
  }

分析

  1. 构造函数里监听surfaceChange来设置SurfaceTexture/SurfaceHolder
  2. start 函数里直接调用mCamera.startPreview();
2.3 更新代码
public void initCamera(int cameraId, float aspectRatio, SurfaceTexture surfaceTexture){
	this.mSurfaceTexture = surfaceTexture;
	...
}

public void startPreview(){
	//这里兜底再做一次权限检查防止无权限出错
	if(CheckHasPermission(CAMERA_PERMISSION)){
		Toast("无相机权限")
		return;
	}
	if(isPreviewing){
		Toast("重复初始化")
		return;
	}
	if(mCamera == null){
		//这里因为openCamera底层是异步的在极端情况下,mCamera会由于时许问题在此位null
		return;
	}
	try{
		//mCamera.startPreview() 经常会抛异常错误信息位startPreview fail. 该异常一部分通常与自动对焦有关系,所以这里try-catch cancelAutoFocus.
		//cancelAutoFocus
		mCamera.cancelAutoFocus();
	}catch(Exception e){
		
	}
	synchronize(Lock){
		if(acquireLock(timeot = 2000)){
			Log.w("timeout");
		}
		mCamera.setPreviewDisplay(mSurfaceTexture);
		//previewCallBack监听回调,通知UI层。
		mCamera.setPreviewCallBack(new PreviewCallback(){
			void onPreviewframe(byte[] data, Camera camera){
				releaseLock();
				if(isPreviewing) return;
				isPreviewing = true;
				CameraManager.of().onCameraPreviewed();=
			}
		})
		try{
			mCamera.startPreview();
		}catch(Exception e){
			Log.e(TAG, "exp info = "+e.getInfos());
			//重试逻辑
			retryStartPreview();
		}
	}
}
2.4 releaseCamera

源码如下:

    
    public final void release() {
        native_release();
        mFaceDetectionRunning = false;
        releaseAppOps();
    }

官方Demo代码如下:

    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
            mCallback.onCameraClosed();
        }
    }

更新代码如下:

public void releaseCamera(){
	if(mCamera == null) return;
	synchronized(Lock){
		try{
			if(acquireLock(timeout = 2000)){
				Log.e(TAG, "timeout")
			}
			mCamera.stopPreview();
			mCamera.release();
			mCamera = null;
			releaseLock();
		}catch(Exception e){
			...
		}
	}
}

至此Camera1Impl初始化销毁流程阐述完毕。下篇将会对所有伪代码进行汇总总结:
Camera1初始化销毁流程(七) —— 伪代码

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5694641.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-17
下一篇2022-12-17

发表评论

登录后才能评论

评论列表(0条)

    保存