小米Mi A20 Lite下ImageAnalysis.Analyzer的analyze方法仅执行一次报错
问题根因
该问题是小米特定机型的相机HAL层定制实现和通用安卓CameraX逻辑不兼容导致,结合你的代码来看有2个核心触发点:
- 遗漏了
mediaImage为空分支下的imageProxy释放逻辑,未被释放的实例会占满深度为1的队列 - 重复关闭
mediaImage和imageProxy,部分小米ROM的资源计数逻辑存在bug,重复释放会被识别为未释放
解决步骤
- 补全所有分支下的
imageProxy释放逻辑,用try-finally块保证无论处理是否成功、mediaImage是否为空,都会执行释放操作 - 移除手动关闭
mediaImage的代码,imageProxy.close()会自动释放其持有的系统图像资源 - 针对小米机型添加兼容配置,强制指定图像输出格式,避免ROM自动切换格式导致的资源泄漏
修正后的代码
ImageAnalysis构建代码
val imageAnalysis = builder .setBackpressureStrategy(ImageAnalysis.STRATEGY_BLOCK_PRODUCER) .setImageQueueDepth(1) // 新增:强制指定YUV格式,适配小米机型 .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888) .build()
analyze方法实现代码
@SuppressLint("UnsafeOptInUsageError") override fun analyze(imageProxy: ImageProxy) { try { val mediaImage = imageProxy.image ?: return val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees) val scanner = BarcodeScanning.getClient(options) scanner.process(image) .addOnSuccessListener { barcodes: List<Barcode?> -> if (barcodes.isNotEmpty()) { EventBus.getDefault().post(OnRetrievedSuccess(barcodes)) } } .addOnFailureListener { EventBus.getDefault().post(OnRetrievedFailure()) } } finally { // 所有分支最终都会执行释放操作 imageProxy.close() } }
可选验证方案
如果修改后问题仍存在,可临时将背压策略替换为ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST验证是否是阻塞策略的适配问题,该策略下系统会自动丢弃未处理的旧帧,不会出现队列占满的异常。
内容的提问来源于stack exchange,提问作者Facundo Farall
相关产品推荐
相关产品推荐

