Android扫码异常:MlKitAnalyzer仅首次触发,重启Activity后失效
排查与解决方法
问题根源定位
首次启动正常、二次启动失效并出现SurfaceView - queueBuffer: BufferQueue has been abandoned错误,核心原因是相机资源未正确释放,导致第二次启动时无法正常获取Surface实例,进而使MlKitAnalyzer无法接收相机帧数据;同时代码中存在条码格式数组初始化的逻辑错误,可能加剧资源异常问题。
具体修复步骤
1. 修复Executor关闭逻辑
cameraExecutor.shutdown()是平缓关闭,可能残留未完成任务导致资源泄漏,改用shutdownNow()强制终止所有任务:
@Override protected void onDestroy() { super.onDestroy(); logger.info("destroy scanner activity"); // 立即终止所有线程池任务,避免资源残留 cameraExecutor.shutdownNow(); if (cameraController != null) { cameraController.clearImageAnalysisAnalyzer(); } if (barcodeScanner != null) { barcodeScanner.close(); } }
2. 移除手动解绑CameraController
LifecycleCameraController已绑定到Activity生命周期,会自动在Activity销毁时处理解绑逻辑,手动调用unbind()会导致生命周期状态不一致,引发Surface资源异常,直接删除cameraController.unbind()代码。
3. 修复条码格式数组初始化错误
原代码循环起始索引错误,导致finalFormats[0]为无效的0值,修改循环逻辑:
// 替换原finalFormats初始化代码 int[] finalFormats = formats.stream().mapToInt(Integer::intValue).toArray(); // 修复扫描器选项构建逻辑 BarcodeScannerOptions scannerOptions; if (formats.isEmpty()) { scannerOptions = new BarcodeScannerOptions.Builder() .setBarcodeFormats(Barcode.FORMAT_QR_CODE) .build(); } else { // 拆分第一个格式与剩余格式,适配setBarcodeFormats的参数要求 scannerOptions = new BarcodeScannerOptions.Builder() .setBarcodeFormats(formats.get(0), Arrays.copyOfRange(finalFormats, 1, finalFormats.length)) .build(); } barcodeScanner = BarcodeScanning.getClient(scannerOptions);
4. 调整finish()执行时机
在分析器回调中先停止分析器,再结束Activity,避免流程冲突:
cameraController.setImageAnalysisAnalyzer(cameraExecutor, new MlKitAnalyzer(List.of(barcodeScanner), COORDINATE_SYSTEM_VIEW_REFERENCED, cameraExecutor, (result) -> { logger.info("Got scanner result {}", result); if (result == null) return; List<Barcode> barcodeResults = result.getValue(barcodeScanner); if (barcodeResults == null || barcodeResults.isEmpty() || barcodeResults.get(0) == null) { return; } Barcode item = barcodeResults.get(0); Intent intent = new Intent(); intent.putExtra("data", item.getRawValue()); setResult(MyBarcodeScanner.REQUEST_CODE, intent); // 先清除分析器,再终止Activity cameraController.clearImageAnalysisAnalyzer(); finish(); }));
5. 升级CameraX与ML Kit依赖
使用最新稳定版依赖,避免旧版本的生命周期管理bug:
implementation "androidx.camera:camera-core:1.3.0" implementation "androidx.camera:camera-camera2:1.3.0" implementation "androidx.camera:camera-lifecycle:1.3.0" implementation "androidx.camera:camera-view:1.3.0" implementation "com.google.mlkit:barcode-scanning:17.2.0"
内容的提问来源于stack exchange,提问作者Chi




