Xamarin Android使用ZXing校验QR码不符合条件时触发Java空指针异常
崩溃原因定位
你遇到的Java.Lang.NullPointerException: 尝试调用Context.getApplicationInfo()空指针,直接触发源是给AlertDialog.Builder传入了无效的上下文对象。
当前代码里写new AlertDialog.Builder(this),如果HandleResult方法是放在ZXing扫码回调类、独立的扫码处理类中,这里的this既不是有效的Activity实例,也没有初始化完成的上下文引用,Builder初始化时需要通过传入的Context读取应用包信息,空引用场景下就会直接抛出这个异常。
现有代码的其他潜在风险
- 无边界的数组访问:直接调用
cadena.Split()后就访问arreglo[0],没有判断QR文本是否为空、Split后的数组长度是否足够,遇到短文本、空内容的QR码时会直接触发数组越界异常 - 冗余的无效逻辑:代码里的
for (int i = 0; i < arreglo.Length; i++)循环没有实际作用,循环内部没有使用循环变量i,每次迭代都会重复给同一个Label赋值,平白增加无意义的UI操作;如果Split后的数组长度不足4,访问arreglo[3]还会触发越界 - 跨线程UI操作风险:ZXing的扫码回调默认运行在后台线程,直接在回调里修改控件文本、弹对话框,会触发Android的UI线程校验异常
修正后的核心代码
public void HandleResult(ZXing.Result rawResult) { // 拦截空QR内容 if (string.IsNullOrWhiteSpace(rawResult?.Text)) { ShowInvalidQrPrompt(); return; } string cadena = rawResult.Text.Trim(); // 拆分时自动过滤空值,避免无效数组项 string[] arreglo = cadena.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries); // 拦截长度不足的异常QR if (arreglo.Length < 4) { ShowInvalidQrPrompt(); return; } if (arreglo[0] == "MOVIL:" || arreglo[0] == "MOVIL,") { arreglo[0] = arreglo[0].Replace("MOVIL:", "MOVIL"); arreglo[0] = arreglo[0].Replace("MOVIL,", "MOVIL"); } if (arreglo[0] == "MOVIL") { // 所有UI操作切回主线程执行 mainActivity.RunOnUiThread(() => { mainActivity.lbl_movil.Text = arreglo[1]; mainActivity.lbl_placa.Text = arreglo[3]; mainActivity.scannerView.StopCamera(); mainActivity.scannerView.Visibility = Android.Views.ViewStates.Invisible; }); } else { ShowInvalidQrPrompt(); } } // 统一封装非法QR提示逻辑 private void ShowInvalidQrPrompt() { mainActivity.RunOnUiThread(() => { // 传入已初始化的MainActivity实例作为上下文,避免空引用 AlertDialog.Builder alerta = new AlertDialog.Builder(mainActivity); alerta.SetTitle("No hay compatibilidad"); alerta.SetMessage("Por favor scanear un codigo correcto"); alerta.SetPositiveButton("确认", (sender, args) => { // 提示后自动重启扫码,避免界面卡在错误状态 mainActivity.scannerView.StartCamera(); }); alerta.Show(); }); }
关键修正点说明
- 弹窗时不再使用无效的
this作为上下文,直接传入全局持有的、已经完成初始化的mainActivity实例,从根源上解决Context空引用导致的getApplicationInfo()崩溃 - 全链路增加边界判断,提前拦截空内容、长度不足的异常QR,避免数组越界
- 删除原代码中无意义的for循环,消除重复的UI赋值操作
- 所有涉及控件修改、弹窗的逻辑统一通过
RunOnUiThread切回Android UI主线程执行,符合系统UI操作的线程规则 - 抽离公共的非法提示逻辑,用户确认弹窗后自动重启相机扫码,优化交互流程
内容的提问来源于stack exchange,提问作者cosmos multi
相关产品推荐
相关产品推荐

