0
votes

I have an activity in MonoForAndroid that makes use of Zxing.Net.Mobile for scanning barcodes on Android. Everything works fine in terms of scanning and returnning results. However, when I try to handle any events on the scanOverlay, I get nullReferenceException. My code is below, any help would be appreciated.

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);
    }
}

All this code above is working fine. However, when I try to handle Done button on the layout, I get the 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);
        }
  }

Details of the exception below

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
Please post the exception details, including stacktrace.Stephen Cleary
Thanks Stephen, added the details of the exception aboveHas AlTaiar

2 Answers

0
votes

Can't comment due to lack of reputation so posting here.

We had a similar issue with another third party application going out of scope. Have you done any level of thread safety checking? Maybe your ZxingBarcodeScanner can only be accessed via the thread which created it, i.e. the thread which called "StartScanSession".

0
votes

I could not find any problem with the way I had set up the methods and events of the Zxing library. Especially after doing the same settings on MonoTounch and all worked fine. Thus, I went into the source code to see what does the scanner.Cancel() method does internally. I found that it just calls the Cancel() static method on the ZxingActivity, so I did that from my code and all seemed to work fine. This is probably not the most elegant solution, and I have reported an issue on the Zxing.Net.Mobile repo on github (here), but for now this works, and I hope it could help someone else too. I also have a full post detailing my experience with using this library on MonoDroid in case anybody needs it here.

so the fix was replacing this line (from the above code):

ZxingBarcodeScanner.Cancel();

with this line:

ZxingActivity.RequestCancel();