发布于2026-07-05 阅读(0)
扫一扫,手机访问
在 Android 上做连续扫码,很多人第一反应是“循环 + 阻塞等待”,结果写出来的代码要么 ANR,要么莫名其妙地崩溃。其实,扫码本身是异步事件——摄像头一直在预览,检测到二维码就触发回调。这个模型天然就不适合用同步思维去驾驭。
那么,正确的思路是什么?简单说就是:把整个扫描流程设计成一条回调驱动的链。每次成功解码后,在 onDecoded 回调里决定要不要开启下一次扫描。不需要什么 wait/notify,也不需要搞一个线程在那傻等——这些操作在 Android 主线程上简直是雷区,wait() 一用,轻则崩溃,重则 ANR。
下面这段代码演示了如何连续扫描 10 次,每次拿到结果后自动开始下一轮,直到全部完成才释放资源:
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 -> {
// 注意:onDecoded 是在后台线程触发的
runOnUiThread(() -> {
Toast.makeText(MainActivity.this,
"Scan #" + (scanCount + 1) + ": " + result.getText(),
Toast.LENGTH_SHORT).show();
});
scanCount++;
if (scanCount < TOTAL_SCANS) {
// 自动开始下一次扫描(无需用户点击)
mCodeScanner.startPreview();
} else {
// 全部完成
mCodeScanner.releaseResources();
Toast.makeText(this,
"All " + TOTAL_SCANS + " scans completed.",
Toast.LENGTH_LONG).show();
}
});
// 首次启动扫描
mCodeScanner.startPreview();
}几个关键点值得拎出来说清楚:
startPreview() 是非阻塞的,调用后立即返回,真正的解码在后台进行。UI 更新必须切回主线程——这就是 runOnUiThread() 的用处。onDecoded 是唯一的“扫描完成”信号。所有后续逻辑,包括计数、重启、终止,都放在这里写,干净利落。startPreview() 不会造成泄漏,但任务结束后一定要调用 releaseResources() 释放摄像头,否则下次扫码或退出页面时可能出问题。Handler.postDelayed() 在 N 秒无扫码时提示用户);支持手动中断(加一个“停止扫描”按钮调用 stopPreview());如果连续扫到的可能是同一个码,可以用 Set 做去重。这种回调驱动的设计完全贴合 Android 生命周期与事件模型,代码简洁、易维护,而且天然线程安全——不用加锁,不用轮询,一切顺其自然。这也就是为什么说它才是现代 Android 扫码开发的推荐做法。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8