游乐游手机版
首页/编程语言/文章详情

安卓连续QR码扫描按序等待识别实现方法

时间:2026-07-10 06:37
基于code-scanner库,采用回调驱动方式实现连续QR码扫描:每次成功解码后在onDecoded()中触发下一轮扫描,通过scanCount控制轮次,避免阻塞主线程。需注意资源释放与状态检查,确保异步编程范式简洁健壮。
本文介绍如何基于 code-scanner 库,通过回调驱动机制实现 Android 上的多轮二维码扫描——每次等待用户成功识别后自动启动下一轮,从而避免阻塞主线程或滥用线程同步。

在 Android 中实现二维码扫描,本质上属于异步事件驱动机制:摄像头持续预览,识别结果通过回调返回。因此,切勿在主线程中使用 wait()/notify() 或循环调用 startPreview() 并尝试“阻塞等待”——这极易引发 ANR(应用无响应),严重时还会因 wait() 不在同步块内而抛出 IllegalMonitorStateException,导致系统无法正常处理。

那么正确的做法是什么?简而言之就是“回调链式触发”:将扫描逻辑封装为独立方法,每次成功解码后,在 onDecoded() 回调中主动发起下一轮扫描。以下代码是实际项目中长期使用的方案,运行稳定可靠。

public class MainActivity extends AppCompatActivity {
    private CodeScanner mCodeScanner;
    private int scanCount = 0;
    private static final int TOTAL_SCANS = 10;

    @Override
    protected void onCreate(Bundle sa vedInstanceState) {
        super.onCreate(sa vedInstanceState);
        setContentView(R.layout.activity_main);

        CodeScannerView scannerView = findViewById(R.id.scanner_view);
        mCodeScanner = new CodeScanner(this, scannerView);

        // 统一设置解码回调
        mCodeScanner.setDecodeCallback(result -> {
            runOnUiThread(() -> {
                Toast.makeText(this, "Scan #" + (scanCount + 1) + ": " + result.getText(),
                               Toast.LENGTH_SHORT).show();
            });
            // 关键:在此处触发下一轮扫描(或终止条件判断)
            scanCount++;
            if (scanCount < TOTAL_SCANS) {
                startNextScan();
            } else {
                Toast.makeText(this, "All " + TOTAL_SCANS + " scans completed!",
                               Toast.LENGTH_LONG).show();
            }
        });

        // 初始启动扫描(例如点击开始按钮或 onResume 中调用)
        findViewById(R.id.btn_start_scan).setOnClickListener(v -> startNextScan());
    }

    private void startNextScan() {
        try {
            mCodeScanner.startPreview(); // 安全调用:确保预览未运行时才启动
        } catch (IllegalStateException e) {
            // 可选:日志记录或提示用户相机已被占用
            Log.w("QRScanner", "Preview already started or camera una vailable", e);
        }
    }

    @Override
    protected void onPause() {
        mCodeScanner.releaseResources();
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 若需在恢复时自动继续扫描,可在此调用 startNextScan()
        // 但通常建议由用户显式触发,避免后台误扫
    }
}

关键要点说明

  • 无阻塞、纯事件驱动机制:onDecoded() 回调天然充当“完成信号”,无需手动同步。
  • 状态可控:借助 scanCount 计数器与条件判断,可精确控制扫描轮次,灵活设定任意次数。
  • 资源安全:在 startPreview() 前添加 try-catch 或状态检查,避免因重复启动引发异常。
  • 生命周期适配:务必在 onPause() 中调用 releaseResources(),否则相机资源持续被占用,不仅影响其他应用,还可能导致内存泄漏。

注意事项

  • 避免在 onDecoded() 中直接调用 mCodeScanner.stopPreview()——库已内部处理预览切换,无需重复操作。
  • 如需设定扫码间隔(例如每次扫描后停顿1秒再开始下一轮),请使用 Handler.postDelayed(),切勿使用忙等待。
  • 在多轮扫描过程中应复用 CodeScanner 实例,避免反复创建与销毁,否则既浪费性能又易引发问题。

此设计完全契合 Android 的异步编程范式,既简洁又健壮,且极易扩展——例如加入扫码结果校验、网络上传或用户确认等逻辑,只需在回调中添加相应代码即可。

来源:https://www.php.cn/faq/2746512.html
上一篇Golang日志正则表达式匹配方法 下一篇Java OpenGL静态导入语法详解:告别GL11前缀冗长写法技巧
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
AWS RDS 数据库配置入门与基础操作指南
编程语言 · 2026-07-10

AWS RDS 数据库配置入门与基础操作指南

本文介绍了AWSRDS的基本概念与核心价值,即提供托管式关系数据库服务,简化运维。详细阐述了创建RDS实例的关键配置步骤,包括引擎选择、实例规格、存储与网络设置。最后,指导读者如何通过多种方式安全连接至数据库实例,并开始进行数据操作,为后续应用开发奠定基础。

PHP MVC中AJAX请求无法调用控制器方法的原因与解决方案
编程语言 · 2026-07-10

PHP MVC中AJAX请求无法调用控制器方法的原因与解决方案

PHPMVC中AJAX请求返回整页HTML的常见原因是控制器方法未正确输出响应或未终止执行,导致框架渲染视图。解决方法是在控制器中设置JSON响应头、输出数据后调用exit()明确终止,同时前端使用小写url和dataType: "json "。

Go语言手动构造rsa.PublicKey:正确初始化大整数模数N完整指南
编程语言 · 2026-07-10

Go语言手动构造rsa.PublicKey:正确初始化大整数模数N完整指南

手动构造RSA公钥时,模数N为*big Int类型,不能直接使用超长十进制字面量,需通过SetString或UnmarshalText方法解析字符串。公钥指数E可直接赋值,推荐65537。生产环境应使用rsa GenerateKey生成密钥对,避免手动构造引发的安全和格式错误。

Go语言实现HTTP定时轮询监控多URL响应时间与状态检测
编程语言 · 2026-07-10

Go语言实现HTTP定时轮询监控多URL响应时间与状态检测

使用Go语言实现HTTP定时轮询监控,通过按行分割与Tab解析URL列表,避免闭包陷阱和nil指针,每个URL启动独立ticker安全并发请求,并配置超时控制与资源关闭,确保响应时间与状态码准确检测。

Tkinter中Label标签在主循环动态更新的正确方法
编程语言 · 2026-07-10

Tkinter中Label标签在主循环动态更新的正确方法

在Tkinter中正确动态更新标签的方法:将标签组件的textvariable参数绑定到一个StringVar变量,然后通过调用该变量的 set()方法更新其值,界面会自动刷新。这样避免直接修改text属性或调用update()。此做法实现数据与界面的解耦,代码更简洁,响应更及时,避免手动同步的闪烁,推荐做法。