uni.scanCode 在低端安卓机上因自动对焦导致卡顿,需显式禁用;应改用 camera 组件手动 focus 实现精准控制,并通过 UI 动画模拟对焦反馈,避免混淆识别成功与光学对焦。

uni.scanCode 默认会自动对焦,但低端 Android 机型反而卡顿
uni.scanCode 在微信小程序和 App 端默认启用自动对焦(autoFocus),但这个“默认开启”在部分联发科芯片 + 安卓 9~10 的设备上会引发严重卡顿、反复失焦、画面模糊——不是你代码写错了,而是 DCloud 封装层的自动对焦检测逻辑拖垮了帧率。
常见错误现象:扫码界面打开后几秒内无响应、预览画面持续抖动、识别成功率骤降;控制台无报错,但 scanCode:fail system error 频发。
- 必须显式关闭自动对焦:
{ autoDecode: false, onlyFromCamera: true, scanType: ['qrCode'] } -
autoDecode: false不仅禁用自动解析,也顺带绕过底层对焦检测逻辑,实测可提升 40%+ 帧率稳定性 - 若业务真需要手动触发对焦(如长按聚焦某区域),应改用
camera组件 +focus方法,而非依赖uni.scanCode的“自动”行为
camera 组件里手动调用 focus() 实现精准对焦
当你用 <camera> 自建扫码页(比如加自定义扫描框、支持前后置切换),才能真正控制对焦时机和位置。此时不能靠“自动”,而要主动调用 focus() 方法。
注意:该方法只在 App 和微信小程序生效,H5 端不支持(浏览器无此 API);且必须确保 camera 组件已就绪、权限已获取。
- 模板中给
<camera ref="cameraRef">加ref,别用id - 在
onReady后用this.$nextTick调用:this.$refs.cameraRef?.focus?.({ x: 0.5, y: 0.5 })(坐标为归一化值,0.5 表示中心) - 安卓部分机型需先调
uni.startSucceedCamera()或等待bindinitdone事件后再调focus(),否则静默失败 - iOS 微信里首次调用需用户手势触发(如点击按钮),否则会被拦截——这是平台限制,无法绕过
扫码框视觉“对焦提示”比真实对焦更重要
用户看到的“对焦成功”,往往不是技术上的焦点锁定,而是 UI 上的反馈。尤其在 uni.scanCode 场景下,你根本无法监听是否真的对焦成功,但可以模拟出“正在对焦 → 对焦完成”的体验。
这比强行让低端机对焦更可靠,也更符合用户预期。
- 在扫码页加一个脉冲动画的环形扫描线(CSS
@keyframes+transform: scale()),表示“正在尝试识别” - 识别成功瞬间,播放短音效 + 扫描线收缩动画 + 显示结果浮层
- 避免使用“对焦中…”文字提示——用户看不懂什么叫“对焦”,但能理解“正在识别”
- 若环境光不足,直接显示补光图标(
<icon type="light">)并禁用扫码按钮,比等scanCode:fail再提示更及时
为什么不能依赖 scanCode 的 success 回调判断对焦状态
因为 uni.scanCode 的 success 只表示“识别到了码”,不代表“对焦完成了”。它可能靠图像模糊匹配、边缘增强或纯算法猜中,和光学对焦无关。很多扫码失败,根本不是没对焦,而是角度/反光/运动模糊导致解码失败。
想验证这点?在光线充足、静止平面上扫同一个二维码,你会发现:即使预览画面明显虚焦,success 仍可能触发;反之,画面清晰但晃动时,success 却不触发。
- 不要在
success里做“对焦成功”埋点或状态更新 - 对焦相关逻辑(如闪光灯开关、缩放控制)必须绑定到
camera组件的生命周期或事件,而非scanCode回调 - App 端若需硬件级对焦控制,得走原生插件(如
uni-plugin-camera),uni.scanCode层面不可控


















