从Async方法内部处理事件

时间:2014-01-15 02:21:11

标签: c# android asynchronous xamarin.android zxing

我在MonoForAndroid中有一项活动,它利用Zxing.Net.Mobile在Android上扫描条形码。在扫描和返回结果方面一切正常。但是,当我尝试处理scanOverlay上的任何事件时,我得到nullReferenceException。我的代码如下,任何帮助将不胜感激。

public async void StartScanSession(ScanSessionEventArgs e)
{
        EnsureLoadingZxingOverlay(e);
        EnsureStartingZxingBarcodeScanner();            
        var zxingOptions = MobileBarcodeScanningOptions.Default;

        var result = await ZxingBarcodeScanner.Scan(zxingOptions);
        HandleScanResult(result, e);
 }

private void HandleScanResult(ZXing.Result result, ScanSessionEventArgs e)
{
    if (result != null && e.OnFinishCallBack != null)
    {
        var scanResult = new ScanResult { ShouldStopScanning = false, BarcodeText = result.Text, ScanTime = result.Timestamp, BarcodeFormat = result.BarcodeFormat.ToString(), RawBytes = result.RawBytes };
        e.OnFinishCallBack(scanResult);
    }
}

private void EnsureLoadingZxingOverlay(ScanSessionEventArgs e)
{
    if (ZxingOverlay == null)
    {
        ZxingOverlay = LayoutInflater.FromContext(this).Inflate(Resource.Layout.scan_custom_layout, null);
        ScanLayoutFlashButton = ZxingOverlay.FindViewById<Button>(Resource.Id.ScanLayoutFlashButton);
        ScanLayoutDoneButton = ZxingOverlay.FindViewById<Button>(Resource.Id.ScanLayoutDoneButton);

        UnhookZxingLayoutButtons();
        ScanLayoutFlashButton.Click += (sender, args) => ZxingBarcodeScanner.ToggleTorch();
        ScanLayoutDoneButton.Click += (sender, args) => HandleDoneButtonOnZxingScanLayout(e);
    }
}

以上所有代码都运行良好。但是,当我尝试在布局上处理Done按钮时,我得到NullReferenceException

 private void HandleDoneButtonOnZxingScanLayout(ScanSessionEventArgs e)
 {
       var result = new ScanResult { ShouldStopScanning = true };
       if (e.OnFinishCallBack != null && ZxingBarcodeScanner != null)
       {
           // at this line below, ZxingBarcodeScanner is null, 
           // but I am sure I have initiated before wiring the event
           // I am guessing it is something to do with the context of the async method??
            ZxingBarcodeScanner.Cancel();
            e.OnFinishCallBack(result);
        }
  }

下面的例外情况

UNHANDLED EXCEPTION: System.NullReferenceException: Object reference not set to an instance of an object
at Leopard.Mobile.Screens.QVgaPortrait.MainScreen.HandleDoneButtonOnZxingScanLayout (Leopard.Mobile.Business.Event.ScanSessionEventArgs) [0x0001e] in ...\MainScreen.cs:178
at Leopard.Mobile.Screens.QVgaPortrait.MainScreen/c__DisplayClass8.b__6 (object,System.EventArgs) [0x00000] in ...\MainScreen.cs:156
at Android.Views.View/IOnClickListenerImplementor.OnClick (Android.Views.View) [0x0000d] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.10.1-branch/d23a19bf/source/monodroid/src/Mono.Android/platforms/android-14/src/generated/Android.Views.View.cs:1615
at Android.Views.View/IOnClickListenerInvoker.n_OnClick_Landroid_view_View_ (intptr,intptr,intptr) [0x00011] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.10.1-branch/d23a19bf/source/monodroid/src/Mono.Android/platforms/android-14/src/generated/Android.Views.View.cs:1582
at (wrapper dynamic-method) object.49957671-33c0-4b79-8c3b-36f419ebfaaa (intptr,intptr,intptr) 

2 个答案:

答案 0 :(得分:0)

由于缺乏声誉而无法发表评论,因此在此发布。

我们遇到了与另一个超出范围的第三方应用程序类似的问题。你做过任何级别的线程安全检查吗?也许您的 ZxingBarcodeScanner 只能通过创建它的线程访问,即调用“StartScanSession”的线程。

答案 1 :(得分:0)

我找不到设置Zxing库的方法和事件的方式有任何问题。特别是在MonoTounch上进行相同的设置后,一切正常。因此,我进入了源代码,看看scanner.Cancel()方法在内部做了什么。我发现它只是调用Cancel()上的static ZxingActivity方法,所以我从我的代码中做到了这一切,所有似乎都运行良好。 这可能不是最优雅的解决方案,我在github(here)上的Zxing.Net.Mobile repo上报告了一个问题,但是现在这个有用了,我希望它也可以帮助其他人。我还有一篇完整的文章,详细介绍了我在MonoDroid上使用此库的经验,以防有人需要here

所以修复程序正在替换此行(来自上面的代码):

ZxingBarcodeScanner.Cancel();

这一行:

ZxingActivity.RequestCancel();