如何停止ZXing.Net.Maui中CameraBarcodeReaderView运作?及优化实现
解决ZXing.Net.Maui CameraBarcodeReaderView弹窗关闭后仍活跃的问题
直接停止扫描的方法
在SecondPage中主动控制扫描状态,确保弹窗关闭前切断相机资源:
- 先在XAML中给
CameraBarcodeReaderView命名:
<zxing:CameraBarcodeReaderView x:Name="BarcodeReader" BarcodesDetected="BarcodesDetected" />
- 在返回主页面的逻辑中先停止扫描,再关闭弹窗:
public async void ReturnMainPage(string code) { // 停止扫描 BarcodeReader.IsScanning = false; // 部分版本可调用StopScanning()替代上述设置 // BarcodeReader.StopScanning(); pather_clients.code = code; await App.Current.MainPage.Navigation.PopModalAsync(); WeakReferenceMessenger.Default.Send(MainPage); }
或者在页面消失的生命周期方法中统一处理,避免漏触发:
protected override void OnDisappearing() { base.OnDisappearing(); if (BarcodeReader != null) { BarcodeReader.IsScanning = false; // 取消事件订阅,避免内存泄漏 BarcodeReader.BarcodesDetected -= BarcodesDetected; } }
确保SecondPage被正确释放
除了停止扫描,还要清理页面的引用和事件绑定,避免内存泄漏导致相机资源无法释放:
- 取消
BarcodesDetected事件的订阅(如上例) - 避免外部强引用持有
SecondPage实例(比如构造函数传入的MainPage可改用弱引用或通过Messenger间接传递,不要直接持有页面对象)
更优的实现方案
1. 使用导航返回结果传递数据
Maui原生支持通过导航返回值传递结果,无需全局变量或Messenger:
在MainPage中打开SecondPage时:
var secondPage = new SecondPage(); await Navigation.PushModalAsync(secondPage); var scanResult = await secondPage.Navigation.GetNavigationResultAsync(); if (scanResult is string code) { pather_clients.code = code; }
在SecondPage中返回结果:
protected void BarcodesDetected(object sender, BarcodeDetectionEventArgs e) { if (detected == 0) { detected = 1; BarcodeReader.IsScanning = false; Navigation.SetNavigationResult(e.Results[0].Value); await Navigation.PopModalAsync(); } }
2. MVVM模式下的解耦实现
如果采用MVVM架构,可将扫码逻辑封装到ViewModel中:
- ViewModel实现
IDisposable接口,在Dispose方法中停止扫描并清理资源 - 页面绑定ViewModel的
IsScanning属性,自动控制扫描状态 - 通过
WeakReferenceMessenger传递扫码结果,避免页面间直接引用
内容的提问来源于stack exchange,提问作者Roberto Oropeza
相关产品推荐
相关产品推荐

