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

使用CameraX图像分析用例扫码后如何避免Intent被多次启动?

多次触发Intent的根因
  • ML Kit的二维码识别是异步操作,你在onSuccess里调用clearAnalyzer()只会停止后续新的帧提交给分析器,但已经进入异步处理队列的多个帧识别任务还是会陆续回调成功,触发多次onSuccess执行跳转逻辑
  • 现有代码没有加状态锁,只要识别到符合条件的二维码就会触发回调,不会判断是否已经执行过跳转逻辑
解决方案

1. 增加执行状态锁,避免重复触发逻辑

在扫码Activity中新增布尔变量标记是否已经识别到二维码,只有未识别的状态下才执行跳转逻辑,识别成功后立刻锁死状态。
修改后的Activity侧代码:

// 扫码Activity顶部新增成员变量
private var isQRCodeDetected = false

// 原来的onSuccess回调修改为:
override fun onSuccess(qrString: String?) {
    // 先判断状态,已经识别过就直接返回
    if (isQRCodeDetected || qrString == null) return
    isQRCodeDetected = true
    
    imageAnalysis.clearAnalyzer()
    Toast.makeText(this@ActivityQR,qrString,Toast.LENGTH_SHORT).show()
    Log.d("rty",qrString.toString())
    val visitordetails = Intent(this@ActivityQR, DisplayQR::class.java)
    visitordetails.putExtra("VISITOR_QR", qrString)
    startActivity(visitordetails)
    // 可选:如果扫码页不需要保留,直接finish,彻底避免后续逻辑触发
    finish()
}

2. 优化CodeAnalyzer逻辑,提前终止无效帧处理

在分析器中也增加处理完成标记,收到成功回调后直接忽略后续所有帧,减少不必要的资源消耗,同时避免异步任务重复回调:

class CodeAnalyzer(context: Context, callBackInterface: CallBackInterface):ImageAnalysis.Analyzer {                                       
    private val context: Context = context
    private val callback: CallBackInterface = callBackInterface
    // 新增处理完成标记
    private var isProcessCompleted = false
    // 把BarcodeScanner改成成员变量,不要每次analyze都新建实例
    private val scanner: BarcodeScanner = BarcodeScanning.getClient()

    @SuppressLint("UnsafeOptInUsageError")
    override fun analyze(image: ImageProxy) {
        // 已经处理完成就直接关闭图片返回,不做后续处理
        if (isProcessCompleted) {
            image.close()
            return
        }
        
        val scannedIMage = image.image
        if (scannedIMage != null) {
            val scannedInputImage = InputImage.fromMediaImage(
                scannedIMage,
                image.imageInfo.rotationDegrees
            )
            scanner.process(scannedInputImage).addOnSuccessListener { barCodes ->
                // 回调前也先判断状态,避免异步任务回调时已经处理完成
                if (isProcessCompleted) return@addOnSuccessListener
                for (qrCode in barCodes) {
                    when (qrCode.valueType) {
                        Barcode.TYPE_TEXT -> {
                            val qrString: String? = qrCode.rawValue
                            if (qrString != null) {
                                // 先标记处理完成,再回调
                                isProcessCompleted = true
                                callback.onSuccess(qrString)
                            }
                        }
                    }
                }
            }.addOnFailureListener {
                // 异常无需额外处理
            }.addOnCompleteListener {
                image.close()
            }   
        } else {
            image.close()
        }
    }
}

3. 可选优化:配置Activity启动模式

如果多次跳转的是同一个DisplayQR页面,可以在AndroidManifest.xml里给DisplayQR设置android:launchMode="singleTop",这样栈顶已经是该Activity时不会重复创建新实例。

内容的提问来源于stack exchange,提问作者user14698807

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 13:24:08