You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

小米Mi A20 Lite下ImageAnalysis.Analyzer的analyze方法仅执行一次报错

问题根因

该问题是小米特定机型的相机HAL层定制实现和通用安卓CameraX逻辑不兼容导致,结合你的代码来看有2个核心触发点:

  • 遗漏了mediaImage为空分支下的imageProxy释放逻辑,未被释放的实例会占满深度为1的队列
  • 重复关闭mediaImage和imageProxy,部分小米ROM的资源计数逻辑存在bug,重复释放会被识别为未释放

解决步骤

  1. 补全所有分支下的imageProxy释放逻辑,用try-finally块保证无论处理是否成功、mediaImage是否为空,都会执行释放操作
  2. 移除手动关闭mediaImage的代码,imageProxy.close()会自动释放其持有的系统图像资源
  3. 针对小米机型添加兼容配置,强制指定图像输出格式,避免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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 08:54:09