安卓连续QR码扫描按序等待识别实现方法
基于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 的异步编程范式,既简洁又健壮,且极易扩展——例如加入扫码结果校验、网络上传或用户确认等逻辑,只需在回调中添加相应代码即可。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
AWS RDS 数据库配置入门与基础操作指南
本文介绍了AWSRDS的基本概念与核心价值,即提供托管式关系数据库服务,简化运维。详细阐述了创建RDS实例的关键配置步骤,包括引擎选择、实例规格、存储与网络设置。最后,指导读者如何通过多种方式安全连接至数据库实例,并开始进行数据操作,为后续应用开发奠定基础。
PHP MVC中AJAX请求无法调用控制器方法的原因与解决方案
PHPMVC中AJAX请求返回整页HTML的常见原因是控制器方法未正确输出响应或未终止执行,导致框架渲染视图。解决方法是在控制器中设置JSON响应头、输出数据后调用exit()明确终止,同时前端使用小写url和dataType: "json "。
Go语言手动构造rsa.PublicKey:正确初始化大整数模数N完整指南
手动构造RSA公钥时,模数N为*big Int类型,不能直接使用超长十进制字面量,需通过SetString或UnmarshalText方法解析字符串。公钥指数E可直接赋值,推荐65537。生产环境应使用rsa GenerateKey生成密钥对,避免手动构造引发的安全和格式错误。
Go语言实现HTTP定时轮询监控多URL响应时间与状态检测
使用Go语言实现HTTP定时轮询监控,通过按行分割与Tab解析URL列表,避免闭包陷阱和nil指针,每个URL启动独立ticker安全并发请求,并配置超时控制与资源关闭,确保响应时间与状态码准确检测。
Tkinter中Label标签在主循环动态更新的正确方法
在Tkinter中正确动态更新标签的方法:将标签组件的textvariable参数绑定到一个StringVar变量,然后通过调用该变量的 set()方法更新其值,界面会自动刷新。这样避免直接修改text属性或调用update()。此做法实现数据与界面的解耦,代码更简洁,响应更及时,避免手动同步的闪烁,推荐做法。
- 热门数据榜
相关攻略
2026-07-10 06:41
2026-07-10 06:40
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

