Camera2 API自动对焦锁定异常:调用AF后连拍卡顿问题
核心问题定位
从日志可见,afState持续为4(对应CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN),说明自动对焦始终处于扫描状态,未完成锁定。lockFocus()中focusLockLatch.await(500, TimeUnit.MILLISECONDS)超时后触发unlockFocus(),但流程中的线程处理、锁机制存在多处问题,最终导致拍摄时卡顿。
具体问题点及修复
1. focusLockLatch初始化时机错误
process()方法中才初始化focusLockLatch,但lockFocus()里已提前调用await(),会导致空指针或等待永远无法触发。
修复:
在lockFocus()触发对焦前初始化focusLockLatch:
protected void lockFocus() { Log.v(TAG, "lockFocus()"); if (mCaptureSession == null) { return; } try { if (focusMode == Mode.AUTO) { // 提前初始化CountDownLatch focusLockLatch = new CountDownLatch(1); mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); mState = STATE_WAITING_LOCK; mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler); if (focusLockLatch.await(500, TimeUnit.MILLISECONDS)) { startCapture(); } else { unlockFocus(); } } else { startCapture(); } } catch (CameraAccessException e) { OnCameraErrorListener.handle(mCameraErrorCallback, e); } catch (InterruptedException e) { throw new RuntimeException(e); } }
同时移除process()中的初始化代码:
// 删除这段冗余初始化 if (focusLockLatch == null) { focusLockLatch = new CountDownLatch(1); }
2. lockFocus()中await()阻塞主线程
若lockFocus()在主线程调用,await()会直接阻塞UI线程,引发应用卡顿。
修复:
将lockFocus()的核心逻辑移至后台线程执行,避免阻塞主线程:
protected void lockFocus() { Log.v(TAG, "lockFocus()"); if (mCaptureSession == null) { return; } if (focusMode != Mode.AUTO) { startCapture(); return; } // 切换到后台线程处理对焦等待逻辑 mBackgroundHandler.post(() -> { try { focusLockLatch = new CountDownLatch(1); mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); mState = STATE_WAITING_LOCK; mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler); if (focusLockLatch.await(500, TimeUnit.MILLISECONDS)) { // 若startCapture涉及UI操作,切回主线程执行 runOnUiThread(this::startCapture); } else { runOnUiThread(this::unlockFocus); } } catch (CameraAccessException e) { OnCameraErrorListener.handle(mCameraErrorCallback, e); } catch (InterruptedException e) { throw new RuntimeException(e); } }); }
3. 重复定义unlockFocus()方法
代码中存在两个完全相同的unlockFocus()方法,编译时会报错,运行时也会导致逻辑混乱。
修复:
删除其中一个重复的方法,仅保留一份即可。
4. 自动对焦触发逻辑冗余
autoFocus()中调用setRepeatingRequest()触发对焦,lockFocus()中又再次触发一次对焦,导致对焦流程冲突。
修复:
调整流程:让autoFocus()仅负责启动对焦扫描,lockFocus()仅负责等待锁定状态并触发拍摄,避免重复触发对焦。
5. unlockFocus()中未重置focusLockLatch
未重置focusLockLatch会导致下一次对焦时状态异常。
修复:
在unlockFocus()末尾添加重置逻辑:
focusLockLatch = null;
额外优化建议
- 增加对焦超时后的重试逻辑,避免单次超时就放弃对焦
- 检查
startCapture()方法,确保拍摄的耗时操作在后台线程执行 - 日志中添加
CONTROL_AF_MODE的打印,确认对焦模式设置正确
内容的提问来源于stack exchange,提问作者Akshar Kalathiya

