2017-03-12 182 views
0

我正在創建一個支持棄用和新相機API的應用程序。第一個像魅力一樣工作,但我正在苦於與Camera2 API。在測試階段,我注意到了奇怪的行爲。測試設備是三星Galaxy S5採用Android 6.0.1 當我按下電源/結束鍵,然後返回到應用程序,這是我所得到的(這不會發生每次):Camera2 API和java.lang.IllegalStateException

03-12 16:14:32.704 24117-24117/pl.tripper.tripper E/MainActivity: onPause 
03-12 16:14:32.774 24117-24128/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] dequeueBuffer: BufferQueue has been abandoned 
03-12 16:14:32.784 24117-24145/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] queueBuffer: BufferQueue has been abandoned 
03-12 16:14:33.044 24117-24128/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] cancelBuffer: BufferQueue has been abandoned 
03-12 16:14:33.044 24117-24145/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] cancelBuffer: BufferQueue has been abandoned 
03-12 16:14:33.054 24117-24129/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] cancelBuffer: BufferQueue has been abandoned 
03-12 16:14:33.054 24117-24128/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-24117-2] cancelBuffer: BufferQueue has been abandoned 
03-12 16:14:33.264 24117-24117/pl.tripper.tripper E/CameraNewApi: cameraComponentsReleased 
03-12 16:14:33.264 24117-24117/pl.tripper.tripper E/CameraNewApi: StopCameraThread 
03-12 16:14:33.264 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewRemoved 
03-12 16:14:33.264 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceDestroyed 
03-12 16:14:33.634 24117-24117/pl.tripper.tripper E/MainActivity: onCreate 
03-12 16:14:33.634 24117-24117/pl.tripper.tripper E/MainActivity: onResume 
03-12 16:14:33.634 24117-24117/pl.tripper.tripper E/CameraNewApi: startCameraThread 
03-12 16:14:33.634 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewCreated 
03-12 16:14:33.644 24117-24117/pl.tripper.tripper E/CameraNewApi: initCamera 
03-12 16:14:33.674 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceCreated 
03-12 16:14:33.674 24117-24117/pl.tripper.tripper E/CameraNewApi: openCamera 
03-12 16:14:33.914 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceChanged 
03-12 16:14:33.914 24117-25053/pl.tripper.tripper E/CameraNewApi: onOpened 
03-12 16:14:33.914 24117-25053/pl.tripper.tripper E/CameraNewApi: createCameraPreview 
03-12 16:14:33.934 24117-24117/pl.tripper.tripper E/MainActivity: onPause 
03-12 16:14:34.174 24117-24117/pl.tripper.tripper E/CameraNewApi: cameraComponentsReleased 
03-12 16:14:34.174 24117-25053/pl.tripper.tripper E/CameraNewApi: onConfigured 
03-12 16:14:34.174 24117-24117/pl.tripper.tripper E/CameraNewApi: StopCameraThread 
03-12 16:14:34.174 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewRemoved 
03-12 16:14:34.184 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceDestroyed 
03-12 16:14:34.914 24117-24117/pl.tripper.tripper E/MainActivity: onResume 
03-12 16:14:34.914 24117-24117/pl.tripper.tripper E/CameraNewApi: startCameraThread 
03-12 16:14:34.924 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewCreated 
03-12 16:14:34.924 24117-24117/pl.tripper.tripper E/CameraNewApi: initCamera 
03-12 16:14:34.964 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceCreated 
03-12 16:14:34.964 24117-24117/pl.tripper.tripper E/CameraNewApi: openCamera 
03-12 16:14:35.294 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceChanged 
03-12 16:14:35.294 24117-25121/pl.tripper.tripper E/CameraNewApi: onOpened 
03-12 16:14:35.294 24117-25121/pl.tripper.tripper E/CameraNewApi: createCameraPreview 
03-12 16:14:35.354 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceChanged 
03-12 16:14:35.374 24117-24117/pl.tripper.tripper E/MainActivity: onPause 
03-12 16:14:35.384 24117-25121/pl.tripper.tripper E/CameraNewApi: onConfigured 
03-12 16:14:35.594 24117-24117/pl.tripper.tripper E/CameraNewApi: cameraComponentsReleased 
03-12 16:14:35.594 24117-25121/pl.tripper.tripper E/CameraNewApi: Session was closed or camera device has been closed. 
                    java.lang.IllegalStateException: CameraDevice was already closed 
                     at android.hardware.camera2.impl.CameraDeviceImpl.checkIfCameraClosedOrInError(CameraDeviceImpl.java:1997) 
                     at android.hardware.camera2.impl.CameraDeviceImpl.submitCaptureRequest(CameraDeviceImpl.java:844) 
                     at android.hardware.camera2.impl.CameraDeviceImpl.setRepeatingRequest(CameraDeviceImpl.java:899) 
                     at android.hardware.camera2.impl.CameraCaptureSessionImpl.setRepeatingRequest(CameraCaptureSessionImpl.java:236) 
                     at pl.tripper.tripper.camera.CameraNewApi$2.onConfigured(CameraNewApi.java:107) 
                     at java.lang.reflect.Method.invoke(Native Method) 
                     at android.hardware.camera2.dispatch.InvokeDispatcher.dispatch(InvokeDispatcher.java:39) 
                     at android.hardware.camera2.dispatch.HandlerDispatcher$1.run(HandlerDispatcher.java:65) 
                     at android.os.Handler.handleCallback(Handler.java:739) 
                     at android.os.Handler.dispatchMessage(Handler.java:95) 
                     at android.os.Looper.loop(Looper.java:158) 
                     at android.os.HandlerThread.run(HandlerThread.java:61) 
03-12 16:14:35.594 24117-24117/pl.tripper.tripper E/CameraNewApi: StopCameraThread 
03-12 16:14:35.594 24117-25121/pl.tripper.tripper E/CameraNewApi: cameraComponentsReleased 
03-12 16:14:35.594 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewRemoved 
03-12 16:14:35.604 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceDestroyed 
03-12 16:14:35.644 24117-24117/pl.tripper.tripper E/MainActivity: onCreate 
03-12 16:14:35.654 24117-24117/pl.tripper.tripper E/MainActivity: onResume 
03-12 16:14:35.654 24117-24117/pl.tripper.tripper E/CameraNewApi: startCameraThread 
03-12 16:14:35.654 24117-24117/pl.tripper.tripper E/CameraApiManager: cameraPreviewCreated 
03-12 16:14:35.654 24117-24117/pl.tripper.tripper E/CameraNewApi: initCamera 
03-12 16:14:35.694 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceCreated 
03-12 16:14:35.694 24117-24117/pl.tripper.tripper E/CameraNewApi: openCamera 
03-12 16:14:35.934 24117-24117/pl.tripper.tripper E/CameraNewApi: onSurfaceChanged 
03-12 16:14:35.934 24117-25184/pl.tripper.tripper E/CameraNewApi: onOpened 
03-12 16:14:35.934 24117-25184/pl.tripper.tripper E/CameraNewApi: createCameraPreview 
03-12 16:14:35.944 24117-24117/pl.tripper.tripper E/ViewRootImpl: sendUserActionEvent() mView == null 
03-12 16:14:35.944 24117-24117/pl.tripper.tripper E/ViewRootImpl: sendUserActionEvent() mView == null 
03-12 16:14:35.994 24117-25184/pl.tripper.tripper E/CameraNewApi: onConfigured 

增加了一些錯誤日誌當方法被調用時。我知道cameraDevice在會話仍然運行時爲空,但我不知道如何解決它。相機在java.lang.IllegalStateException錯誤後仍繼續工作。第二個問題是BufferQueueProducer錯誤,但我無法弄清楚這是從哪裏來的。

03-12 15:47:40.244 30720-30731/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] dequeueBuffer: BufferQueue has been abandoned 03-12 15:47:40.244 30720-30751/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] queueBuffer: BufferQueue has been abandoned 03-12 15:47:40.524 30720-30731/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] cancelBuffer: BufferQueue has been abandoned 03-12 15:47:40.524 30720-30751/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] cancelBuffer: BufferQueue has been abandoned 03-12 15:47:40.524 30720-30732/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] cancelBuffer: BufferQueue has been abandoned 03-12 15:47:40.524 30720-30731/pl.tripper.tripper E/BufferQueueProducer: [SurfaceTexture-1-30720-1] cancelBuffer: BufferQueue has been abandoned

這裏是我的代碼:

MainActivity.class

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     ButterKnife.bind(this); 

     Log.e(TAG, "onCreate"); 
     isImmersiveAvailable(); 
     cameraApiManager = new CameraApiManager(this, this); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     Log.e(TAG, "onResume"); 
     cameraApiManager.createCamera(); 

    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 

     Log.e(TAG, "onPause"); 
     cameraApiManager.releaseCameraAndPreview(); 
    } 

CameraApiManager.class

public class CameraApiManager implements CameraUtility.cameraOpenedListener { 

    private static final String TAG = "CameraApiManager"; 

    private final WeakReference<MainActivity> mainActivity; 
    private Context context; 

    private CameraSourceApi cameraSourceApi; 
    private CameraPreview cameraPreview; 

    public CameraApiManager(Context context, MainActivity mainActivity){ 

     this.mainActivity= new WeakReference<>(mainActivity); 

     cameraSourceApi = new CameraSourceApi<>(new CameraNewApi(context)); 
     this.context = context; 
    } 

    private boolean cameraProgressBarEnable(){ 
     return context.getResources().getBoolean(R.bool.camera_progress_bar_enable); 
    } 

    private void setCameraProgressBarVisibility(final int visibility){ 
     final MainActivity mainActivity = this.mainActivity.get(); 
     if(mainActivity!= null){ 
      // UI/Main Thread 
      if(Looper.myLooper() == Looper.getMainLooper()){ 
       ProgressBar cameraProgressBar = (ProgressBar) mainActivity.findViewById(R.id.camera_progress_bar); 
       cameraProgressBar.setVisibility(visibility); 
      } else { 
       mainActivity.runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         ProgressBar cameraProgressBar = (ProgressBar) mainActivity.findViewById(R.id.camera_progress_bar); 
         cameraProgressBar.setVisibility(visibility); 
        } 
       }); 
      } 
     } 
    } 

    private void showCameraOpenErrorToast(){ 
     Toast.makeText(context, context.getResources().getString(R.string.camera_open_error_toast), Toast.LENGTH_LONG).show(); 
    } 

    private boolean cameraPermissionGranted() { 
     return ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED; 
    } 

    public void createCamera(){ 
     if(cameraPermissionGranted()){ 
      if(cameraProgressBarEnable()){ 
       setCameraProgressBarVisibility(View.VISIBLE); 
      } 
      cameraSourceApi.createCamera(this); 
     } 
    } 

    public void releaseCameraAndPreview(){ 
     if(cameraPermissionGranted()){ 
      cameraSourceApi.releaseCamera(); 
      removeCameraPreview(); 
     } 
    } 

    @Override 
    public void onCameraOpened(boolean succeeded, boolean addPreview, boolean progressBar) { 
     if(addPreview) { 
      if (cameraPreview == null) { 
       Log.e(TAG, "cameraPreviewCreated"); 
       cameraPreview = new CameraPreview(context, cameraSourceApi); 
       addCameraPreview(); 
      } 
     } 
     if(!progressBar){ 
      if(cameraProgressBarEnable()){ 
       setCameraProgressBarVisibility(View.GONE); 
      } 
     } 
     if(!succeeded){ 
      showCameraOpenErrorToast(); 
     } 
    } 

    private void addCameraPreview(){ 
     MainActivity mainActivity = this.mainActivity.get(); 
     if(mainActivity != null && cameraPreview != null){ 
      FrameLayout preview = (FrameLayout) mainActivity.findViewById(R.id.camera_preview); 
      preview.addView(cameraPreview); 
     } 
    } 

    private void removeCameraPreview(){ 
     MainActivity mainActivity = this.mainActivity.get(); 
     if(mainActivity!= null && cameraPreview != null){ 
      Log.e(TAG, "cameraPreviewRemoved"); 
      FrameLayout preview = (FrameLayout) mainActivity.findViewById(R.id.camera_preview); 
      preview.removeView(cameraPreview); 
      cameraPreview = null; 
     } 
    } 

    class CameraSourceApi<T extends CameraUtility> implements CameraUtility{ 

     private T camera; 

     CameraSourceApi(T camera){ 
      this.camera = camera; 
     } 

     @Override 
     public void createCamera(CameraUtility.cameraOpenedListener cameraOpenedListener) { 
      camera.createCamera(cameraOpenedListener); 
     } 

     @Override 
     public void releaseCamera() { 
      camera.releaseCamera(); 
     } 

     @Override 
     public void onSurfaceCreated(SurfaceHolder surfaceHolder) { 
      camera.onSurfaceCreated(surfaceHolder); 
     } 

     @Override 
     public void onSurfaceChanged(SurfaceHolder surfaceHolder, int width, int height) { 
      camera.onSurfaceChanged(surfaceHolder, width, height); 
     } 

     @Override 
     public void onSurfaceDestroyed(SurfaceHolder surfaceHolder) { 
      camera.onSurfaceDestroyed(surfaceHolder); 
     } 
    } 
} 

CameraNewApi.class

@TargetApi(21) 
class CameraNewApi implements CameraUtility { 

    private static final String TAG = "CameraNewApi"; 

    private Semaphore cameraOpenCloseLock = new Semaphore(1); 

    private CameraUtility.cameraOpenedListener cameraOpenedListener; 

    private Context context; 

    private Handler backgroundHandler; 
    private HandlerThread backgroundThread; 

    private SurfaceHolder surfaceHolder; 

    private String backFacingCameraId; 
    private CaptureRequest.Builder captureRequestBuilder; 
    private CameraDevice cameraDevice; 
    private CameraCaptureSession cameraCaptureSessions; 

    CameraNewApi(Context context){ 
     this.context = context; 
    } 


    private final CameraDevice.StateCallback cameraDeviceStateCallback = new CameraDevice.StateCallback() { 
     @Override 
     public void onOpened(@NonNull CameraDevice camera) { 
      Log.e(TAG, "onOpened"); 
      cameraOpenCloseLock.release(); 
      cameraDevice = camera; 
      if(surfaceHolder != null){ 
       createCameraPreview(); 
      } else { 
       releaseCameraComponents(); 
      } 
     } 

     @Override 
     public void onDisconnected(@NonNull CameraDevice camera) { 
      Log.d(TAG, "deviceCallback.onDisconnected() start"); 
      Log.e(TAG, "onDisconnected"); 
      if(cameraOpenedListener != null) { 
       cameraOpenedListener.onCameraOpened(false, false, false); 
      } 
      cameraOpenCloseLock.release(); 
      camera.close(); 
      cameraDevice = null; 
     } 

     @Override 
     public void onError(@NonNull CameraDevice camera, int error) { 
      Log.e(TAG, "onError"); 
      Log.d(TAG, "deviceCallback.onError() start"); 
      if(cameraOpenedListener != null) { 
       cameraOpenedListener.onCameraOpened(false, false, false); 
      } 
      cameraOpenCloseLock.release(); 
      camera.close(); 
      cameraDevice = null; 
     } 
    }; 

    private final CameraCaptureSession.StateCallback captureSessionStateCallback = new CameraCaptureSession.StateCallback() { 
     @Override 
     public void onConfigured(@NonNull CameraCaptureSession session) { 
      Log.e(TAG, "onConfigured"); 
      if(cameraDevice != null){ 
       cameraCaptureSessions = session; 
       captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); 
       try { 
        if(cameraOpenedListener != null) { 
         cameraOpenedListener.onCameraOpened(true, false, false); 
        } 
        session.setRepeatingRequest(captureRequestBuilder.build(), null, backgroundHandler); 
       } catch (CameraAccessException e) { 
        Log.e(TAG, "Camera has been disconnected", e); 
       } catch (IllegalStateException e){ 
        Log.e(TAG, "Session was closed or camera device has been closed. ", e); 
        releaseCameraComponents(); 
       } 
      } 
     } 

     @Override 
     public void onConfigureFailed(@NonNull CameraCaptureSession session) { 
      Log.d(TAG, "Capture session configure failed: " + session); 
      Log.e(TAG, "onConfigureFailed"); 
     } 
    }; 

    @Override 
    public void createCamera(CameraUtility.cameraOpenedListener cameraOpenedListener) { 
     this.cameraOpenedListener = cameraOpenedListener; 

     startBackgroundThread(); 
     if(cameraOpenedListener != null){ 
      cameraOpenedListener.onCameraOpened(true, true, true); 
     } 
     initCamera(); 
    } 

    private void releaseCameraComponents(){ 
     try{ 
      cameraOpenCloseLock.acquire(); 
      if(cameraCaptureSessions != null){ 
       cameraCaptureSessions.close(); 
       cameraCaptureSessions = null; 
      } 
      if(cameraDevice != null){ 
       cameraDevice.close(); 
       cameraDevice = null; 
      } 
      if(surfaceHolder != null){ 
       surfaceHolder = null; 
      } 
      if(cameraOpenedListener != null){ 
       cameraOpenedListener = null; 
      } 
      Log.e(TAG, "cameraComponentsReleased"); 
     } catch (InterruptedException e) { 
      throw new RuntimeException("Interrupted while trying to lock camera closing.", e); 
     } finally { 
      cameraOpenCloseLock.release(); 
     } 
    } 
    @Override 
    public void releaseCamera() { 
     releaseCameraComponents(); 
     stopBackgroundThread(); 
    } 

    @Override 
    public void onSurfaceCreated(SurfaceHolder surfaceHolder) { 
     Log.e(TAG, "onSurfaceCreated"); 
     this.surfaceHolder = surfaceHolder; 
     openCamera(); 
    } 

    @Override 
    public void onSurfaceChanged(SurfaceHolder surfaceHolder, int width, int height) { 
     Log.e(TAG, "onSurfaceChanged"); 
     setSurfaceSize(width, height); 
    } 

    @Override 
    public void onSurfaceDestroyed(SurfaceHolder surfaceHolder) { 
     Log.e(TAG, "onSurfaceDestroyed"); 
    } 

    private void startBackgroundThread() { 
     Log.e(TAG, "startCameraThread"); 
     backgroundThread = new HandlerThread("CameraBackground"); 
     backgroundThread.start(); 
     backgroundHandler = new Handler(backgroundThread.getLooper()); 
    } 

    private void stopBackgroundThread() { 
     Log.e(TAG, "StopCameraThread"); 
     backgroundThread.quitSafely(); 
     try { 
      backgroundThread.join(); 
      backgroundThread = null; 
      backgroundHandler = null; 
     } catch (InterruptedException e) { 
      Log.e(TAG, "Error message: ", e); 
     } 
    } 

    private void initCamera(){ 
     Log.e(TAG, "initCamera"); 
     CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); 

     try{ 
      for (String cameraId : cameraManager.getCameraIdList()) { 
       CameraCharacteristics characteristics 
         = cameraManager.getCameraCharacteristics(cameraId); 

       // Use back camera 
       Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING); 
       if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) { 
        backFacingCameraId = cameraId; 
        break; 
       } 
      } 
      if(backFacingCameraId == null){ 
       Log.d(TAG, "Could not detect a camera"); 
      } 
     } catch (CameraAccessException e) { 
      Log.e(TAG, "Could not get camera list", e); 
     } 
    } 

    private void openCamera(){ 
     Log.e(TAG, "openCamera"); 
     CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); 
     try{ 
      if(backFacingCameraId != null && cameraDevice == null){ 
       try{ 
        if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { 
         throw new RuntimeException("Time out waiting to lock camera opening."); 
        } 
        cameraManager.openCamera(backFacingCameraId, cameraDeviceStateCallback, backgroundHandler); 
       } catch (InterruptedException e) { 
        throw new RuntimeException("Interrupted while trying to lock camera opening.", e); 
       } 
      } 
     } catch(SecurityException e){ 
      Log.e(TAG, "Camera permission is not granted", e); 
     } catch(CameraAccessException e){ 
      Log.e(TAG, "Could not open camera", e); 
     } 
    } 

    private void createCameraPreview(){ 

     Log.e(TAG, "createCameraPreview"); 
     Surface surface = surfaceHolder.getSurface(); 

     List<Surface> surfaceList = Collections.singletonList(surface); 

     try { 
      captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 
      captureRequestBuilder.addTarget(surface); 
      cameraDevice.createCaptureSession(surfaceList, captureSessionStateCallback, null); 
     } catch (CameraAccessException e){ 
      Log.e(TAG, "Could not create capture session for camera: " + cameraDevice.getId(), e); 
     } catch (IllegalStateException e){ 
      Log.e(TAG, "Camera has been closed", e); 
     } 
    } 

CameraUtility.interface

interface CameraUtility { 

    void createCamera(CameraUtility.cameraOpenedListener cameraOpenedListener); 
    void releaseCamera(); 
    void onSurfaceCreated(SurfaceHolder surfaceHolder); 
    void onSurfaceChanged(SurfaceHolder surfaceHolder, int width, int height); 
    void onSurfaceDestroyed(SurfaceHolder surfaceHolder); 

    interface cameraOpenedListener{ 
     void onCameraOpened(boolean succeeded, boolean addPreview, boolean progressBar); 
    } 
} 

UPDATE

這就是爲什麼它不會每次發生。在調用onPause之後立即發生錯誤,會話開始重複請求以維護預覽(onConfigured)。然後cameraComponentsReleased觸發器完成所有清理,包括當前的CameraDevice對象。仍然沒有線索如何管理這種情況。

03-13 12:12:24.375 17555-17555/pl.tripper.tripper E/MainActivity: onPause 
03-13 12:12:24.395 17555-20454/pl.tripper.tripper E/CameraNewApi: onConfigured 
03-13 12:12:24.625 17555-17555/pl.tripper.tripper E/CameraNewApi: cameraComponentsReleased 
03-13 12:12:24.625 17555-17555/pl.tripper.tripper E/CameraNewApi: StopCameraThread 
03-13 12:12:24.625 17555-20454/pl.tripper.tripper E/CameraNewApi: Session was closed or camera device has been closed. 
                    java.lang.IllegalStateException: CameraDevice was already closed 
                     at android.hardware.camera2.impl.CameraDeviceImpl.checkIfCameraClosedOrInError(CameraDeviceImpl.java:1997) 
                     at android.hardware.camera2.impl.CameraDeviceImpl.submitCaptureRequest(CameraDeviceImpl.java:844) 
                     at android.hardware.camera2.impl.CameraDeviceImpl.setRepeatingRequest(CameraDeviceImpl.java:899) 
                     at android.hardware.camera2.impl.CameraCaptureSessionImpl.setRepeatingRequest(CameraCaptureSessionImpl.java:236) 
                     at pl.tripper.tripper.camera.CameraNewApi$2.onConfigured(CameraNewApi.java:114) 
                     at java.lang.reflect.Method.invoke(Native Method) 
                     at android.hardware.camera2.dispatch.InvokeDispatcher.dispatch(InvokeDispatcher.java:39) 
                     at android.hardware.camera2.dispatch.HandlerDispatcher$1.run(HandlerDispatcher.java:65) 
                     at android.os.Handler.handleCallback(Handler.java:739) 
                     at android.os.Handler.dispatchMessage(Handler.java:95) 
                     at android.os.Looper.loop(Looper.java:158) 
                     at android.os.HandlerThread.run(HandlerThread.java:61) 
03-13 12:12:24.625 17555-20454/pl.tripper.tripper E/CameraNewApi: Camera onClosed 
03-13 12:12:24.625 17555-17555/pl.tripper.tripper E/CameraApiManager: cameraPreviewRemoved 

回答

1
java.lang.IllegalStateException: CameraDevice was already closed 

這意味着CameraDevice是某些人在某些情況下關閉。 (例如:內存不足)要處理這個問題,可以在StateCallback - cameraDeviceStateCallback中添加onClosed()回調。

android.hardware.camera2.CameraDevice.StateCallback.onClosed(CameraDevice) 

更新時間:

它看起來像一個競爭條件。 IMO,releaseCameraComponents和onConfigured應該同步。

private void releaseCameraComponents(){ 
    synchronized(lock) { 
      .... 
    } 
} 
.... 

@Override 
public void onConfigured(@NonNull CameraCaptureSession session) { 
    synchronized(lock) { 
     .... 
    } 
} 
+0

增加了一些新的信息質疑 – sheddar

+0

@You金 - 我認爲你是對的。使用camera2Basic示例有幾種可能的競爭條件,但onConfigured回調實際上是打開序列中的最後一步,所以將它包含在任何同步計劃中都是有意義的。 – Mick

1
mCameraOpenCloseLock.release() 

此信號燈應相機createCaptureSession行動,以防止多個線程之間的資源衝突之後被釋放。攝像頭打開後,源代碼太早釋放信號量。暫停應用程序將關閉導致錯誤的相機。

爲了測試它,mCameraOpenCloseLock.release()之前調用finish(),你不會看到錯誤