Camera2 API 和 java.lang.IllegalStateException
Posted
技术标签:
【中文标题】Camera2 API 和 java.lang.IllegalStateException【英文标题】:Camera2 API and java.lang.IllegalStateException 【发布时间】:2017-08-02 14:36:33 【问题描述】:我正在创建一个支持已弃用和新相机 API 的应用。第一个就像一个魅力,但我正在努力使用 Camera2 API。在测试阶段,我注意到奇怪的行为。测试设备为三星 Galaxy S5 安卓 6.0.1 当我按下电源/结束键然后返回应用程序时,这就是我得到的(并非每次都发生):
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);
更新
这就是为什么它不会每次都发生。调用 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)
更新:
它看起来像一个竞争条件。在日志中,17555-17555 releaseCameraComponents
和 17555-20454 onConfigured
回调在不同的线程上被调用。 IMO,cameraCaptureSessions 应该在releaseCameraComponents
和onConfigured
中同步。
private void releaseCameraComponents()
synchronized(lock)
....
....
@Override
public void onConfigured(@NonNull CameraCaptureSession session)
synchronized(lock)
....
【讨论】:
@You Kim - 我认为你是对的。 camera2Basic 示例有一些可能的竞争条件,但 onConfigured 回调实际上是打开序列中的最后一步,因此将其包含在任何同步计划中是有意义的。 如果您不知道如何像我一样使用它,请查看docs.oracle.com/javase/tutorial/essential/concurrency/…。 我更喜欢处理线程或单个调度程序,以处理摄像头、音频、电话、BLE 等硬件资源,尤其是当资源具有状态时。另外我更喜欢避免在资源回调中调用资源 API。【参考方案2】:mCameraOpenCloseLock.release()
这个 Semaphore 应该在相机 createCaptureSession 动作之后释放,以防止多个线程之间的资源冲突。源代码在相机打开后过早释放信号量。暂停应用程序将关闭导致错误的相机。
要测试它,在mCameraOpenCloseLock.release()
之前调用finish()
,你不会看到错误
【讨论】:
你能解释一下如何使用它吗?【参考方案3】:1> 首先,请创建一个信号量'mCameraOpenCloseLock',以防止应用在关闭相机之前退出。 使用谷歌推荐的例子:- https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java
2> 这个信号量是在CameraDevice.StateCallback 的onOpened() 中释放的,这是不正确的,所以请删除它。它应该在 createCameraPreviewSession() 中的 onConfigured() 结束时释放。这意味着在相机预览会话成功完成后释放信号量 mCameraOpenCloseLock。
【讨论】:
以上是关于Camera2 API 和 java.lang.IllegalStateException的主要内容,如果未能解决你的问题,请参考以下文章
使用 Android Camera2 API 进行人脸检测和画圆
问题支持Android相机的API和camera2 API问题,怎么解决